(function (root, factory) {
    if (typeof define === &apos;function&apos; &amp;&amp; define.amd) {
        // AMD. Register as an anonymous module.
        define([], factory);
    } else if (typeof module === &apos;object&apos; &amp;&amp; module.exports) {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory();
    } else {
        // Browser globals (root is window)
        root.echarts = factory();
    }
}(this, function () {var require, define;
(function () {
    var mods = {};

    define = function (id, deps, factory) {
        mods[id] = {
            id: id,
            deps: deps,
            factory: factory,
            defined: 0,
            exports: {},
            require: createRequire(id)
        };
    };

    require = createRequire(&apos;&apos;);

    function normalize(id, baseId) {
        if (!baseId) {
            return id;
        }

        if (id.indexOf(&apos;.&apos;) === 0) {
            var basePath = baseId.split(&apos;/&apos;);
            var namePath = id.split(&apos;/&apos;);
            var baseLen = basePath.length - 1;
            var nameLen = namePath.length;
            var cutBaseTerms = 0;
            var cutNameTerms = 0;

            pathLoop: for (var i = 0; i &lt; nameLen; i++) {
                switch (namePath[i]) {
                    case &apos;..&apos;:
                        if (cutBaseTerms &lt; baseLen) {
                            cutBaseTerms++;
                            cutNameTerms++;
                        }
                        else {
                            break pathLoop;
                        }
                        break;
                    case &apos;.&apos;:
                        cutNameTerms++;
                        break;
                    default:
                        break pathLoop;
                }
            }

            basePath.length = baseLen - cutBaseTerms;
            namePath = namePath.slice(cutNameTerms);

            return basePath.concat(namePath).join(&apos;/&apos;);
        }

        return id;
    }

    function createRequire(baseId) {
        var cacheMods = {};

        function localRequire(id, callback) {
            if (typeof id === &apos;string&apos;) {
                var exports = cacheMods[id];
                if (!exports) {
                    exports = getModExports(normalize(id, baseId));
                    cacheMods[id] = exports;
                }

                return exports;
            }
            else if (id instanceof Array) {
                callback = callback || function () {};
                callback.apply(this, getModsExports(id, callback, baseId));
            }
        };

        return localRequire;
    }

    function getModsExports(ids, factory, baseId) {
        var es = [];
        var mod = mods[baseId];

        for (var i = 0, l = Math.min(ids.length, factory.length); i &lt; l; i++) {
            var id = normalize(ids[i], baseId);
            var arg;
            switch (id) {
                case &apos;require&apos;:
                    arg = (mod &amp;&amp; mod.require) || require;
                    break;
                case &apos;exports&apos;:
                    arg = mod.exports;
                    break;
                case &apos;module&apos;:
                    arg = mod;
                    break;
                default:
                    arg = getModExports(id);
            }
            es.push(arg);
        }

        return es;
    }

    function getModExports(id) {
        var mod = mods[id];
        if (!mod) {
            throw new Error(&apos;No &apos; + id);
        }

        if (!mod.defined) {
            var factory = mod.factory;
            var factoryReturn = factory.apply(
                this,
                getModsExports(mod.deps || [], factory, id)
            );
            if (typeof factoryReturn !== &apos;undefined&apos;) {
                mod.exports = factoryReturn;
            }
            mod.defined = 1;
        }

        return mod.exports;
    }
}());
define(&apos;echarts/component/polar&apos;, [&apos;require&apos;, &apos;../coord/polar/polarCreator&apos;, &apos;./angleAxis&apos;, &apos;./radiusAxis&apos;, &apos;../echarts&apos;], function (require) {
    &apos;use strict&apos;;
    require(&apos;../coord/polar/polarCreator&apos;);
    require(&apos;./angleAxis&apos;);
    require(&apos;./radiusAxis&apos;);
    // Polar view
    require(&apos;../echarts&apos;).extendComponentView({ type: &apos;polar&apos; });
});
define(&apos;echarts/chart/pie&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../echarts&apos;, &apos;./pie/PieSeries&apos;, &apos;./pie/PieView&apos;, &apos;../action/createDataSelectAction&apos;, &apos;../visual/dataColor&apos;, &apos;./pie/pieLayout&apos;, &apos;../processor/dataFilter&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var echarts = require(&apos;../echarts&apos;);
    require(&apos;./pie/PieSeries&apos;);
    require(&apos;./pie/PieView&apos;);
    require(&apos;../action/createDataSelectAction&apos;)(&apos;pie&apos;, [
        {
            type: &apos;pieToggleSelect&apos;,
            event: &apos;pieselectchanged&apos;,
            method: &apos;toggleSelected&apos;
        },
        {
            type: &apos;pieSelect&apos;,
            event: &apos;pieselected&apos;,
            method: &apos;select&apos;
        },
        {
            type: &apos;pieUnSelect&apos;,
            event: &apos;pieunselected&apos;,
            method: &apos;unSelect&apos;
        }
    ]);
    echarts.registerVisual(zrUtil.curry(require(&apos;../visual/dataColor&apos;), &apos;pie&apos;));
    echarts.registerLayout(zrUtil.curry(require(&apos;./pie/pieLayout&apos;), &apos;pie&apos;));
    echarts.registerProcessor(zrUtil.curry(require(&apos;../processor/dataFilter&apos;), &apos;pie&apos;));
});
define(&apos;echarts/chart/radar&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../echarts&apos;, &apos;../component/radar&apos;, &apos;./radar/RadarSeries&apos;, &apos;./radar/RadarView&apos;, &apos;../visual/dataColor&apos;, &apos;../visual/symbol&apos;, &apos;./radar/radarLayout&apos;, &apos;../processor/dataFilter&apos;, &apos;./radar/backwardCompat&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var echarts = require(&apos;../echarts&apos;);
    // Must use radar component
    require(&apos;../component/radar&apos;);
    require(&apos;./radar/RadarSeries&apos;);
    require(&apos;./radar/RadarView&apos;);
    echarts.registerVisual(zrUtil.curry(require(&apos;../visual/dataColor&apos;), &apos;radar&apos;));
    echarts.registerVisual(zrUtil.curry(require(&apos;../visual/symbol&apos;), &apos;radar&apos;, &apos;circle&apos;, null));
    echarts.registerLayout(require(&apos;./radar/radarLayout&apos;));
    echarts.registerProcessor(zrUtil.curry(require(&apos;../processor/dataFilter&apos;), &apos;radar&apos;));
    echarts.registerPreprocessor(require(&apos;./radar/backwardCompat&apos;));
});
define(&apos;echarts/echarts&apos;, [&apos;require&apos;, &apos;zrender/core/env&apos;, &apos;./model/Global&apos;, &apos;./ExtensionAPI&apos;, &apos;./CoordinateSystem&apos;, &apos;./model/OptionManager&apos;, &apos;./model/Component&apos;, &apos;./model/Series&apos;, &apos;./view/Component&apos;, &apos;./view/Chart&apos;, &apos;./util/graphic&apos;, &apos;zrender&apos;, &apos;zrender/core/util&apos;, &apos;zrender/tool/color&apos;, &apos;zrender/mixin/Eventful&apos;, &apos;zrender/core/timsort&apos;, &apos;./loading/default&apos;, &apos;./visual/seriesColor&apos;, &apos;./preprocessor/backwardCompat&apos;, &apos;./data/List&apos;, &apos;./model/Model&apos;, &apos;./util/number&apos;, &apos;./util/format&apos;, &apos;zrender/core/matrix&apos;, &apos;zrender/core/vector&apos;], function (require) {
    var env = require(&apos;zrender/core/env&apos;);
    var GlobalModel = require(&apos;./model/Global&apos;);
    var ExtensionAPI = require(&apos;./ExtensionAPI&apos;);
    var CoordinateSystemManager = require(&apos;./CoordinateSystem&apos;);
    var OptionManager = require(&apos;./model/OptionManager&apos;);
    var ComponentModel = require(&apos;./model/Component&apos;);
    var SeriesModel = require(&apos;./model/Series&apos;);
    var ComponentView = require(&apos;./view/Component&apos;);
    var ChartView = require(&apos;./view/Chart&apos;);
    var graphic = require(&apos;./util/graphic&apos;);
    var zrender = require(&apos;zrender&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var colorTool = require(&apos;zrender/tool/color&apos;);
    var Eventful = require(&apos;zrender/mixin/Eventful&apos;);
    var timsort = require(&apos;zrender/core/timsort&apos;);
    var each = zrUtil.each;
    var PRIORITY_PROCESSOR_FILTER = 1000;
    var PRIORITY_PROCESSOR_STATISTIC = 5000;
    var PRIORITY_VISUAL_LAYOUT = 1000;
    var PRIORITY_VISUAL_GLOBAL = 2000;
    var PRIORITY_VISUAL_CHART = 3000;
    var PRIORITY_VISUAL_COMPONENT = 4000;
    var PRIORITY_VISUAL_BRUSH = 5000;
    // Main process have three entries: `setOption`, `dispatchAction` and `resize`,
    // where they must not be invoked nestedly, except the only case: invoke
    // dispatchAction with updateMethod &quot;none&quot; in main process.
    // This flag is used to carry out this rule.
    // All events will be triggered out side main process (i.e. when !this[IN_MAIN_PROCESS]).
    var IN_MAIN_PROCESS = &apos;__flag_in_main_process&apos;;
    var HAS_GRADIENT_OR_PATTERN_BG = &apos;_hasGradientOrPatternBg&apos;;
    function createRegisterEventWithLowercaseName(method) {
        return function (eventName, handler, context) {
            // Event name is all lowercase
            eventName = eventName &amp;&amp; eventName.toLowerCase();
            Eventful.prototype[method].call(this, eventName, handler, context);
        };
    }
    /**
     * @module echarts~MessageCenter
     */
    function MessageCenter() {
        Eventful.call(this);
    }
    MessageCenter.prototype.on = createRegisterEventWithLowercaseName(&apos;on&apos;);
    MessageCenter.prototype.off = createRegisterEventWithLowercaseName(&apos;off&apos;);
    MessageCenter.prototype.one = createRegisterEventWithLowercaseName(&apos;one&apos;);
    zrUtil.mixin(MessageCenter, Eventful);
    /**
     * @module echarts~ECharts
     */
    function ECharts(dom, theme, opts) {
        opts = opts || {};
        // Get theme by name
        if (typeof theme === &apos;string&apos;) {
            theme = themeStorage[theme];
        }
        /**
         * @type {string}
         */
        this.id;
        /**
         * Group id
         * @type {string}
         */
        this.group;
        /**
         * @type {HTMLDomElement}
         * @private
         */
        this._dom = dom;
        /**
         * @type {module:zrender/ZRender}
         * @private
         */
        this._zr = zrender.init(dom, {
            renderer: opts.renderer || &apos;canvas&apos;,
            devicePixelRatio: opts.devicePixelRatio
        });
        /**
         * @type {Object}
         * @private
         */
        this._theme = zrUtil.clone(theme);
        /**
         * @type {Array.<module:echarts view="" chart="">}
         * @private
         */
        this._chartsViews = [];
        /**
         * @type {Object.<string, module:echarts="" view="" chart="">}
         * @private
         */
        this._chartsMap = {};
        /**
         * @type {Array.<module:echarts view="" component="">}
         * @private
         */
        this._componentsViews = [];
        /**
         * @type {Object.<string, module:echarts="" view="" component="">}
         * @private
         */
        this._componentsMap = {};
        /**
         * @type {module:echarts/ExtensionAPI}
         * @private
         */
        this._api = new ExtensionAPI(this);
        /**
         * @type {module:echarts/CoordinateSystem}
         * @private
         */
        this._coordSysMgr = new CoordinateSystemManager();
        Eventful.call(this);
        /**
         * @type {module:echarts~MessageCenter}
         * @private
         */
        this._messageCenter = new MessageCenter();
        // Init mouse events
        this._initEvents();
        // In case some people write `window.onresize = chart.resize`
        this.resize = zrUtil.bind(this.resize, this);
        // Can&apos;t dispatch action during rendering procedure
        this._pendingActions = [];
        // Sort on demand
        function prioritySortFunc(a, b) {
            return a.prio - b.prio;
        }
        timsort(visualFuncs, prioritySortFunc);
        timsort(dataProcessorFuncs, prioritySortFunc);
    }
    var echartsProto = ECharts.prototype;
    /**
     * @return {HTMLDomElement}
     */
    echartsProto.getDom = function () {
        return this._dom;
    };
    /**
     * @return {module:zrender~ZRender}
     */
    echartsProto.getZr = function () {
        return this._zr;
    };
    /**
     * @param {Object} option
     * @param {boolean} notMerge
     * @param {boolean} [notRefreshImmediately=false] Useful when setOption frequently.
     */
    echartsProto.setOption = function (option, notMerge, notRefreshImmediately) {
        if (true) {
            zrUtil.assert(!this[IN_MAIN_PROCESS], &apos;`setOption` should not be called during main process.&apos;);
        }
        this[IN_MAIN_PROCESS] = true;
        if (!this._model || notMerge) {
            var optionManager = new OptionManager(this._api);
            var theme = this._theme;
            var ecModel = this._model = new GlobalModel(null, null, theme, optionManager);
            ecModel.init(null, null, theme, optionManager);
        }
        this._model.setOption(option, optionPreprocessorFuncs);
        updateMethods.prepareAndUpdate.call(this);
        this[IN_MAIN_PROCESS] = false;
        this._flushPendingActions();
        !notRefreshImmediately &amp;&amp; this._zr.refreshImmediately();
    };
    /**
     * @DEPRECATED
     */
    echartsProto.setTheme = function () {
        console.log(&apos;ECharts#setTheme() is DEPRECATED in ECharts 3.0&apos;);
    };
    /**
     * @return {module:echarts/model/Global}
     */
    echartsProto.getModel = function () {
        return this._model;
    };
    /**
     * @return {Object}
     */
    echartsProto.getOption = function () {
        return this._model.getOption();
    };
    /**
     * @return {number}
     */
    echartsProto.getWidth = function () {
        return this._zr.getWidth();
    };
    /**
     * @return {number}
     */
    echartsProto.getHeight = function () {
        return this._zr.getHeight();
    };
    /**
     * Get canvas which has all thing rendered
     * @param {Object} opts
     * @param {string} [opts.backgroundColor]
     */
    echartsProto.getRenderedCanvas = function (opts) {
        if (!env.canvasSupported) {
            return;
        }
        opts = opts || {};
        opts.pixelRatio = opts.pixelRatio || 1;
        opts.backgroundColor = opts.backgroundColor || this._model.get(&apos;backgroundColor&apos;);
        var zr = this._zr;
        var list = zr.storage.getDisplayList();
        // Stop animations
        zrUtil.each(list, function (el) {
            el.stopAnimation(true);
        });
        return zr.painter.getRenderedCanvas(opts);
    };
    /**
     * @return {string}
     * @param {Object} opts
     * @param {string} [opts.type=&apos;png&apos;]
     * @param {string} [opts.pixelRatio=1]
     * @param {string} [opts.backgroundColor]
     */
    echartsProto.getDataURL = function (opts) {
        opts = opts || {};
        var excludeComponents = opts.excludeComponents;
        var ecModel = this._model;
        var excludesComponentViews = [];
        var self = this;
        each(excludeComponents, function (componentType) {
            ecModel.eachComponent({ mainType: componentType }, function (component) {
                var view = self._componentsMap[component.__viewId];
                if (!view.group.ignore) {
                    excludesComponentViews.push(view);
                    view.group.ignore = true;
                }
            });
        });
        var url = this.getRenderedCanvas(opts).toDataURL(&apos;image/&apos; + (opts &amp;&amp; opts.type || &apos;png&apos;));
        each(excludesComponentViews, function (view) {
            view.group.ignore = false;
        });
        return url;
    };
    /**
     * @return {string}
     * @param {Object} opts
     * @param {string} [opts.type=&apos;png&apos;]
     * @param {string} [opts.pixelRatio=1]
     * @param {string} [opts.backgroundColor]
     */
    echartsProto.getConnectedDataURL = function (opts) {
        if (!env.canvasSupported) {
            return;
        }
        var groupId = this.group;
        var mathMin = Math.min;
        var mathMax = Math.max;
        var MAX_NUMBER = Infinity;
        if (connectedGroups[groupId]) {
            var left = MAX_NUMBER;
            var top = MAX_NUMBER;
            var right = -MAX_NUMBER;
            var bottom = -MAX_NUMBER;
            var canvasList = [];
            var dpr = opts &amp;&amp; opts.pixelRatio || 1;
            for (var id in instances) {
                var chart = instances[id];
                if (chart.group === groupId) {
                    var canvas = chart.getRenderedCanvas(zrUtil.clone(opts));
                    var boundingRect = chart.getDom().getBoundingClientRect();
                    left = mathMin(boundingRect.left, left);
                    top = mathMin(boundingRect.top, top);
                    right = mathMax(boundingRect.right, right);
                    bottom = mathMax(boundingRect.bottom, bottom);
                    canvasList.push({
                        dom: canvas,
                        left: boundingRect.left,
                        top: boundingRect.top
                    });
                }
            }
            left *= dpr;
            top *= dpr;
            right *= dpr;
            bottom *= dpr;
            var width = right - left;
            var height = bottom - top;
            var targetCanvas = zrUtil.createCanvas();
            targetCanvas.width = width;
            targetCanvas.height = height;
            var zr = zrender.init(targetCanvas);
            each(canvasList, function (item) {
                var img = new graphic.Image({
                        style: {
                            x: item.left * dpr - left,
                            y: item.top * dpr - top,
                            image: item.dom
                        }
                    });
                zr.add(img);
            });
            zr.refreshImmediately();
            return targetCanvas.toDataURL(&apos;image/&apos; + (opts &amp;&amp; opts.type || &apos;png&apos;));
        } else {
            return this.getDataURL(opts);
        }
    };
    var updateMethods = {
            update: function (payload) {
                // console.time &amp;&amp; console.time(&apos;update&apos;);
                var ecModel = this._model;
                var api = this._api;
                var coordSysMgr = this._coordSysMgr;
                var zr = this._zr;
                // update before setOption
                if (!ecModel) {
                    return;
                }
                // Fixme First time update ?
                ecModel.restoreData();
                // TODO
                // Save total ecModel here for undo/redo (after restoring data and before processing data).
                // Undo (restoration of total ecModel) can be carried out in &apos;action&apos; or outside API call.
                // Create new coordinate system each update
                // In LineView may save the old coordinate system and use it to get the orignal point
                coordSysMgr.create(this._model, this._api);
                processData.call(this, ecModel, api);
                stackSeriesData.call(this, ecModel);
                coordSysMgr.update(ecModel, api);
                doVisualEncoding.call(this, ecModel, payload);
                doRender.call(this, ecModel, payload);
                // Set background
                var backgroundColor = ecModel.get(&apos;backgroundColor&apos;) || &apos;transparent&apos;;
                var painter = zr.painter;
                // TODO all use clearColor ?
                if (painter.isSingleCanvas &amp;&amp; painter.isSingleCanvas()) {
                    zr.configLayer(0, { clearColor: backgroundColor });
                } else {
                    // In IE8
                    if (!env.canvasSupported) {
                        var colorArr = colorTool.parse(backgroundColor);
                        backgroundColor = colorTool.stringify(colorArr, &apos;rgb&apos;);
                        if (colorArr[3] === 0) {
                            backgroundColor = &apos;transparent&apos;;
                        }
                    }
                    if (backgroundColor.colorStops || backgroundColor.image) {
                        // Gradient background
                        // FIXME Fixed layer&#xFF1F;
                        zr.configLayer(0, { clearColor: backgroundColor });
                        this[HAS_GRADIENT_OR_PATTERN_BG] = true;
                        this._dom.style.background = &apos;transparent&apos;;
                    } else {
                        if (this[HAS_GRADIENT_OR_PATTERN_BG]) {
                            zr.configLayer(0, { clearColor: null });
                        }
                        this[HAS_GRADIENT_OR_PATTERN_BG] = false;
                        this._dom.style.background = backgroundColor;
                    }
                }    // console.time &amp;&amp; console.timeEnd(&apos;update&apos;);
            },
            updateView: function (payload) {
                var ecModel = this._model;
                // update before setOption
                if (!ecModel) {
                    return;
                }
                ecModel.eachSeries(function (seriesModel) {
                    seriesModel.getData().clearAllVisual();
                });
                doVisualEncoding.call(this, ecModel, payload);
                invokeUpdateMethod.call(this, &apos;updateView&apos;, ecModel, payload);
            },
            updateVisual: function (payload) {
                var ecModel = this._model;
                // update before setOption
                if (!ecModel) {
                    return;
                }
                ecModel.eachSeries(function (seriesModel) {
                    seriesModel.getData().clearAllVisual();
                });
                doVisualEncoding.call(this, ecModel, payload);
                invokeUpdateMethod.call(this, &apos;updateVisual&apos;, ecModel, payload);
            },
            updateLayout: function (payload) {
                var ecModel = this._model;
                // update before setOption
                if (!ecModel) {
                    return;
                }
                doLayout.call(this, ecModel, payload);
                invokeUpdateMethod.call(this, &apos;updateLayout&apos;, ecModel, payload);
            },
            highlight: function (payload) {
                toggleHighlight.call(this, &apos;highlight&apos;, payload);
            },
            downplay: function (payload) {
                toggleHighlight.call(this, &apos;downplay&apos;, payload);
            },
            prepareAndUpdate: function (payload) {
                var ecModel = this._model;
                prepareView.call(this, &apos;component&apos;, ecModel);
                prepareView.call(this, &apos;chart&apos;, ecModel);
                updateMethods.update.call(this, payload);
            }
        };
    /**
     * @param {Object} payload
     * @private
     */
    function toggleHighlight(method, payload) {
        var ecModel = this._model;
        // dispatchAction before setOption
        if (!ecModel) {
            return;
        }
        ecModel.eachComponent({
            mainType: &apos;series&apos;,
            query: payload
        }, function (seriesModel, index) {
            var chartView = this._chartsMap[seriesModel.__viewId];
            if (chartView &amp;&amp; chartView.__alive) {
                chartView[method](seriesModel, ecModel, this._api, payload);
            }
        }, this);
    }
    /**
     * Resize the chart
     */
    echartsProto.resize = function () {
        if (true) {
            zrUtil.assert(!this[IN_MAIN_PROCESS], &apos;`resize` should not be called during main process.&apos;);
        }
        this[IN_MAIN_PROCESS] = true;
        this._zr.resize();
        var optionChanged = this._model &amp;&amp; this._model.resetOption(&apos;media&apos;);
        updateMethods[optionChanged ? &apos;prepareAndUpdate&apos; : &apos;update&apos;].call(this);
        // Resize loading effect
        this._loadingFX &amp;&amp; this._loadingFX.resize();
        this[IN_MAIN_PROCESS] = false;
        this._flushPendingActions();
    };
    var defaultLoadingEffect = require(&apos;./loading/default&apos;);
    /**
     * Show loading effect
     * @param  {string} [name=&apos;default&apos;]
     * @param  {Object} [cfg]
     */
    echartsProto.showLoading = function (name, cfg) {
        if (zrUtil.isObject(name)) {
            cfg = name;
            name = &apos;default&apos;;
        }
        this.hideLoading();
        var el = defaultLoadingEffect(this._api, cfg);
        var zr = this._zr;
        this._loadingFX = el;
        zr.add(el);
    };
    /**
     * Hide loading effect
     */
    echartsProto.hideLoading = function () {
        this._loadingFX &amp;&amp; this._zr.remove(this._loadingFX);
        this._loadingFX = null;
    };
    /**
     * @param {Object} eventObj
     * @return {Object}
     */
    echartsProto.makeActionFromEvent = function (eventObj) {
        var payload = zrUtil.extend({}, eventObj);
        payload.type = eventActionMap[eventObj.type];
        return payload;
    };
    /**
     * @pubilc
     * @param {Object} payload
     * @param {string} [payload.type] Action type
     * @param {boolean} [silent=false] Whether trigger event.
     */
    echartsProto.dispatchAction = function (payload, silent) {
        var actionWrap = actions[payload.type];
        if (!actionWrap) {
            return;
        }
        var actionInfo = actionWrap.actionInfo;
        var updateMethod = actionInfo.update || &apos;update&apos;;
        // if (__DEV__) {
        //     zrUtil.assert(
        //         !this[IN_MAIN_PROCESS],
        //         &apos;`dispatchAction` should not be called during main process.&apos;
        //         + &apos;unless updateMathod is &quot;none&quot;.&apos;
        //     );
        // }
        // May dispatchAction in rendering procedure
        if (this[IN_MAIN_PROCESS]) {
            this._pendingActions.push(payload);
            return;
        }
        this[IN_MAIN_PROCESS] = true;
        var payloads = [payload];
        var batched = false;
        // Batch action
        if (payload.batch) {
            batched = true;
            payloads = zrUtil.map(payload.batch, function (item) {
                item = zrUtil.defaults(zrUtil.extend({}, item), payload);
                item.batch = null;
                return item;
            });
        }
        var eventObjBatch = [];
        var eventObj;
        var isHighlightOrDownplay = payload.type === &apos;highlight&apos; || payload.type === &apos;downplay&apos;;
        for (var i = 0; i &lt; payloads.length; i++) {
            var batchItem = payloads[i];
            // Action can specify the event by return it.
            eventObj = actionWrap.action(batchItem, this._model);
            // Emit event outside
            eventObj = eventObj || zrUtil.extend({}, batchItem);
            // Convert type to eventType
            eventObj.type = actionInfo.event || eventObj.type;
            eventObjBatch.push(eventObj);
            // Highlight and downplay are special.
            isHighlightOrDownplay &amp;&amp; updateMethods[updateMethod].call(this, batchItem);
        }
        updateMethod !== &apos;none&apos; &amp;&amp; !isHighlightOrDownplay &amp;&amp; updateMethods[updateMethod].call(this, payload);
        // Follow the rule of action batch
        if (batched) {
            eventObj = {
                type: actionInfo.event || payload.type,
                batch: eventObjBatch
            };
        } else {
            eventObj = eventObjBatch[0];
        }
        this[IN_MAIN_PROCESS] = false;
        !silent &amp;&amp; this._messageCenter.trigger(eventObj.type, eventObj);
        this._flushPendingActions();
    };
    echartsProto._flushPendingActions = function () {
        var pendingActions = this._pendingActions;
        while (pendingActions.length) {
            var payload = pendingActions.shift();
            this.dispatchAction(payload);
        }
    };
    /**
     * Register event
     * @method
     */
    echartsProto.on = createRegisterEventWithLowercaseName(&apos;on&apos;);
    echartsProto.off = createRegisterEventWithLowercaseName(&apos;off&apos;);
    echartsProto.one = createRegisterEventWithLowercaseName(&apos;one&apos;);
    /**
     * @param {string} methodName
     * @private
     */
    function invokeUpdateMethod(methodName, ecModel, payload) {
        var api = this._api;
        // Update all components
        each(this._componentsViews, function (component) {
            var componentModel = component.__model;
            component[methodName](componentModel, ecModel, api, payload);
            updateZ(componentModel, component);
        }, this);
        // Upate all charts
        ecModel.eachSeries(function (seriesModel, idx) {
            var chart = this._chartsMap[seriesModel.__viewId];
            chart[methodName](seriesModel, ecModel, api, payload);
            updateZ(seriesModel, chart);
            updateProgressiveAndBlend(seriesModel, chart);
        }, this);
        // If use hover layer
        updateHoverLayerStatus(this._zr, ecModel);
    }
    /**
     * Prepare view instances of charts and components
     * @param  {module:echarts/model/Global} ecModel
     * @private
     */
    function prepareView(type, ecModel) {
        var isComponent = type === &apos;component&apos;;
        var viewList = isComponent ? this._componentsViews : this._chartsViews;
        var viewMap = isComponent ? this._componentsMap : this._chartsMap;
        var zr = this._zr;
        for (var i = 0; i &lt; viewList.length; i++) {
            viewList[i].__alive = false;
        }
        ecModel[isComponent ? &apos;eachComponent&apos; : &apos;eachSeries&apos;](function (componentType, model) {
            if (isComponent) {
                if (componentType === &apos;series&apos;) {
                    return;
                }
            } else {
                model = componentType;
            }
            // Consider: id same and type changed.
            var viewId = model.id + &apos;_&apos; + model.type;
            var view = viewMap[viewId];
            if (!view) {
                var classType = ComponentModel.parseClassType(model.type);
                var Clazz = isComponent ? ComponentView.getClass(classType.main, classType.sub) : ChartView.getClass(classType.sub);
                if (Clazz) {
                    view = new Clazz();
                    view.init(ecModel, this._api);
                    viewMap[viewId] = view;
                    viewList.push(view);
                    zr.add(view.group);
                } else {
                    // Error
                    return;
                }
            }
            model.__viewId = viewId;
            view.__alive = true;
            view.__id = viewId;
            view.__model = model;
        }, this);
        for (var i = 0; i &lt; viewList.length;) {
            var view = viewList[i];
            if (!view.__alive) {
                zr.remove(view.group);
                view.dispose(ecModel, this._api);
                viewList.splice(i, 1);
                delete viewMap[view.__id];
            } else {
                i++;
            }
        }
    }
    /**
     * Processor data in each series
     *
     * @param {module:echarts/model/Global} ecModel
     * @private
     */
    function processData(ecModel, api) {
        each(dataProcessorFuncs, function (process) {
            process.func(ecModel, api);
        });
    }
    /**
     * @private
     */
    function stackSeriesData(ecModel) {
        var stackedDataMap = {};
        ecModel.eachSeries(function (series) {
            var stack = series.get(&apos;stack&apos;);
            var data = series.getData();
            if (stack &amp;&amp; data.type === &apos;list&apos;) {
                var previousStack = stackedDataMap[stack];
                if (previousStack) {
                    data.stackedOn = previousStack;
                }
                stackedDataMap[stack] = data;
            }
        });
    }
    /**
     * Layout before each chart render there series, special visual encoding stage
     *
     * @param {module:echarts/model/Global} ecModel
     * @private
     */
    function doLayout(ecModel, payload) {
        var api = this._api;
        each(visualFuncs, function (visual) {
            if (visual.isLayout) {
                visual.func(ecModel, api, payload);
            }
        });
    }
    /**
     * Encode visual infomation from data after data processing
     *
     * @param {module:echarts/model/Global} ecModel
     * @private
     */
    function doVisualEncoding(ecModel, payload) {
        var api = this._api;
        ecModel.clearColorPalette();
        ecModel.eachSeries(function (seriesModel) {
            seriesModel.clearColorPalette();
        });
        each(visualFuncs, function (visual) {
            visual.func(ecModel, api, payload);
        });
    }
    /**
     * Render each chart and component
     * @private
     */
    function doRender(ecModel, payload) {
        var api = this._api;
        // Render all components
        each(this._componentsViews, function (componentView) {
            var componentModel = componentView.__model;
            componentView.render(componentModel, ecModel, api, payload);
            updateZ(componentModel, componentView);
        }, this);
        each(this._chartsViews, function (chart) {
            chart.__alive = false;
        }, this);
        // Render all charts
        ecModel.eachSeries(function (seriesModel, idx) {
            var chartView = this._chartsMap[seriesModel.__viewId];
            chartView.__alive = true;
            chartView.render(seriesModel, ecModel, api, payload);
            chartView.group.silent = !!seriesModel.get(&apos;silent&apos;);
            updateZ(seriesModel, chartView);
            updateProgressiveAndBlend(seriesModel, chartView);
        }, this);
        // If use hover layer
        updateHoverLayerStatus(this._zr, ecModel);
        // Remove groups of unrendered charts
        each(this._chartsViews, function (chart) {
            if (!chart.__alive) {
                chart.remove(ecModel, api);
            }
        }, this);
    }
    var MOUSE_EVENT_NAMES = [
            &apos;click&apos;,
            &apos;dblclick&apos;,
            &apos;mouseover&apos;,
            &apos;mouseout&apos;,
            &apos;mousedown&apos;,
            &apos;mouseup&apos;,
            &apos;globalout&apos;
        ];
    /**
     * @private
     */
    echartsProto._initEvents = function () {
        each(MOUSE_EVENT_NAMES, function (eveName) {
            this._zr.on(eveName, function (e) {
                var ecModel = this.getModel();
                var el = e.target;
                if (el &amp;&amp; el.dataIndex != null) {
                    var dataModel = el.dataModel || ecModel.getSeriesByIndex(el.seriesIndex);
                    var params = dataModel &amp;&amp; dataModel.getDataParams(el.dataIndex, el.dataType) || {};
                    params.event = e;
                    params.type = eveName;
                    this.trigger(eveName, params);
                }    // If element has custom eventData of components
                else if (el &amp;&amp; el.eventData) {
                    this.trigger(eveName, el.eventData);
                }
            }, this);
        }, this);
        each(eventActionMap, function (actionType, eventType) {
            this._messageCenter.on(eventType, function (event) {
                this.trigger(eventType, event);
            }, this);
        }, this);
    };
    /**
     * @return {boolean}
     */
    echartsProto.isDisposed = function () {
        return this._disposed;
    };
    /**
     * Clear
     */
    echartsProto.clear = function () {
        this.setOption({}, true);
    };
    /**
     * Dispose instance
     */
    echartsProto.dispose = function () {
        if (this._disposed) {
            if (true) {
                console.warn(&apos;Instance &apos; + this.id + &apos; has been disposed&apos;);
            }
            return;
        }
        this._disposed = true;
        var api = this._api;
        var ecModel = this._model;
        each(this._componentsViews, function (component) {
            component.dispose(ecModel, api);
        });
        each(this._chartsViews, function (chart) {
            chart.dispose(ecModel, api);
        });
        // Dispose after all views disposed
        this._zr.dispose();
        delete instances[this.id];
    };
    zrUtil.mixin(ECharts, Eventful);
    function updateHoverLayerStatus(zr, ecModel) {
        var storage = zr.storage;
        var elCount = 0;
        storage.traverse(function (el) {
            if (!el.isGroup) {
                elCount++;
            }
        });
        if (elCount &gt; ecModel.get(&apos;hoverLayerThreshold&apos;) &amp;&amp; !env.node) {
            storage.traverse(function (el) {
                if (!el.isGroup) {
                    el.useHoverLayer = true;
                }
            });
        }
    }
    /**
     * Update chart progressive and blend.
     * @param {module:echarts/model/Series|module:echarts/model/Component} model
     * @param {module:echarts/view/Component|module:echarts/view/Chart} view
     */
    function updateProgressiveAndBlend(seriesModel, chartView) {
        // Progressive configuration
        var elCount = 0;
        chartView.group.traverse(function (el) {
            if (el.type !== &apos;group&apos; &amp;&amp; !el.ignore) {
                elCount++;
            }
        });
        var frameDrawNum = +seriesModel.get(&apos;progressive&apos;);
        var needProgressive = elCount &gt; seriesModel.get(&apos;progressiveThreshold&apos;) &amp;&amp; frameDrawNum &amp;&amp; !env.node;
        if (needProgressive) {
            chartView.group.traverse(function (el) {
                // FIXME marker and other components
                if (!el.isGroup) {
                    el.progressive = needProgressive ? Math.floor(elCount++ / frameDrawNum) : -1;
                    if (needProgressive) {
                        el.stopAnimation(true);
                    }
                }
            });
        }
        // Blend configration
        var blendMode = seriesModel.get(&apos;blendMode&apos;) || null;
        if (true) {
            if (!env.canvasSupported &amp;&amp; blendMode &amp;&amp; blendMode !== &apos;source-over&apos;) {
                console.warn(&apos;Only canvas support blendMode&apos;);
            }
        }
        chartView.group.traverse(function (el) {
            // FIXME marker and other components
            if (!el.isGroup) {
                el.setStyle(&apos;blend&apos;, blendMode);
            }
        });
    }
    /**
     * @param {module:echarts/model/Series|module:echarts/model/Component} model
     * @param {module:echarts/view/Component|module:echarts/view/Chart} view
     */
    function updateZ(model, view) {
        var z = model.get(&apos;z&apos;);
        var zlevel = model.get(&apos;zlevel&apos;);
        // Set z and zlevel
        view.group.traverse(function (el) {
            if (el.type !== &apos;group&apos;) {
                z != null &amp;&amp; (el.z = z);
                zlevel != null &amp;&amp; (el.zlevel = zlevel);
            }
        });
    }
    /**
     * @type {Array.<function>}
     * @inner
     */
    var actions = [];
    /**
     * Map eventType to actionType
     * @type {Object}
     */
    var eventActionMap = {};
    /**
     * Data processor functions of each stage
     * @type {Array.<object.<string, function="">&gt;}
     * @inner
     */
    var dataProcessorFuncs = [];
    /**
     * @type {Array.<function>}
     * @inner
     */
    var optionPreprocessorFuncs = [];
    /**
     * Visual encoding functions of each stage
     * @type {Array.<object.<string, function="">&gt;}
     * @inner
     */
    var visualFuncs = [];
    /**
     * Theme storage
     * @type {Object.<key, object="">}
     */
    var themeStorage = {};
    var instances = {};
    var connectedGroups = {};
    var idBase = new Date() - 0;
    var groupIdBase = new Date() - 0;
    var DOM_ATTRIBUTE_KEY = &apos;_echarts_instance_&apos;;
    /**
     * @alias module:echarts
     */
    var echarts = {
            version: &apos;3.2.2&apos;,
            dependencies: { zrender: &apos;3.1.2&apos; }
        };
    function enableConnect(chart) {
        var STATUS_PENDING = 0;
        var STATUS_UPDATING = 1;
        var STATUS_UPDATED = 2;
        var STATUS_KEY = &apos;__connectUpdateStatus&apos;;
        function updateConnectedChartsStatus(charts, status) {
            for (var i = 0; i &lt; charts.length; i++) {
                var otherChart = charts[i];
                otherChart[STATUS_KEY] = status;
            }
        }
        zrUtil.each(eventActionMap, function (actionType, eventType) {
            chart._messageCenter.on(eventType, function (event) {
                if (connectedGroups[chart.group] &amp;&amp; chart[STATUS_KEY] !== STATUS_PENDING) {
                    var action = chart.makeActionFromEvent(event);
                    var otherCharts = [];
                    for (var id in instances) {
                        var otherChart = instances[id];
                        if (otherChart !== chart &amp;&amp; otherChart.group === chart.group) {
                            otherCharts.push(otherChart);
                        }
                    }
                    updateConnectedChartsStatus(otherCharts, STATUS_PENDING);
                    each(otherCharts, function (otherChart) {
                        if (otherChart[STATUS_KEY] !== STATUS_UPDATING) {
                            otherChart.dispatchAction(action);
                        }
                    });
                    updateConnectedChartsStatus(otherCharts, STATUS_UPDATED);
                }
            });
        });
    }
    /**
     * @param {HTMLDomElement} dom
     * @param {Object} [theme]
     * @param {Object} opts
     */
    echarts.init = function (dom, theme, opts) {
        if (true) {
            // Check version
            if (zrender.version.replace(&apos;.&apos;, &apos;&apos;) - 0 &lt; echarts.dependencies.zrender.replace(&apos;.&apos;, &apos;&apos;) - 0) {
                throw new Error(&apos;ZRender &apos; + zrender.version + &apos; is too old for ECharts &apos; + echarts.version + &apos;. Current version need ZRender &apos; + echarts.dependencies.zrender + &apos;+&apos;);
            }
            if (!dom) {
                throw new Error(&apos;Initialize failed: invalid dom.&apos;);
            }
            if (zrUtil.isDom(dom) &amp;&amp; dom.nodeName.toUpperCase() !== &apos;CANVAS&apos; &amp;&amp; (!dom.clientWidth || !dom.clientHeight)) {
                console.warn(&apos;Can\&apos;t get dom width or height&apos;);
            }
        }
        var chart = new ECharts(dom, theme, opts);
        chart.id = &apos;ec_&apos; + idBase++;
        instances[chart.id] = chart;
        dom.setAttribute &amp;&amp; dom.setAttribute(DOM_ATTRIBUTE_KEY, chart.id);
        enableConnect(chart);
        return chart;
    };
    /**
     * @return {string|Array.<module:echarts~echarts>} groupId
     */
    echarts.connect = function (groupId) {
        // Is array of charts
        if (zrUtil.isArray(groupId)) {
            var charts = groupId;
            groupId = null;
            // If any chart has group
            zrUtil.each(charts, function (chart) {
                if (chart.group != null) {
                    groupId = chart.group;
                }
            });
            groupId = groupId || &apos;g_&apos; + groupIdBase++;
            zrUtil.each(charts, function (chart) {
                chart.group = groupId;
            });
        }
        connectedGroups[groupId] = true;
        return groupId;
    };
    /**
     * @return {string} groupId
     */
    echarts.disConnect = function (groupId) {
        connectedGroups[groupId] = false;
    };
    /**
     * Dispose a chart instance
     * @param  {module:echarts~ECharts|HTMLDomElement|string} chart
     */
    echarts.dispose = function (chart) {
        if (zrUtil.isDom(chart)) {
            chart = echarts.getInstanceByDom(chart);
        } else if (typeof chart === &apos;string&apos;) {
            chart = instances[chart];
        }
        if (chart instanceof ECharts &amp;&amp; !chart.isDisposed()) {
            chart.dispose();
        }
    };
    /**
     * @param  {HTMLDomElement} dom
     * @return {echarts~ECharts}
     */
    echarts.getInstanceByDom = function (dom) {
        var key = dom.getAttribute(DOM_ATTRIBUTE_KEY);
        return instances[key];
    };
    /**
     * @param {string} key
     * @return {echarts~ECharts}
     */
    echarts.getInstanceById = function (key) {
        return instances[key];
    };
    /**
     * Register theme
     */
    echarts.registerTheme = function (name, theme) {
        themeStorage[name] = theme;
    };
    /**
     * Register option preprocessor
     * @param {Function} preprocessorFunc
     */
    echarts.registerPreprocessor = function (preprocessorFunc) {
        optionPreprocessorFuncs.push(preprocessorFunc);
    };
    /**
     * @param {number} [priority=1000]
     * @param {Function} processorFunc
     */
    echarts.registerProcessor = function (priority, processorFunc) {
        if (typeof priority === &apos;function&apos;) {
            processorFunc = priority;
            priority = PRIORITY_PROCESSOR_FILTER;
        }
        if (true) {
            if (isNaN(priority)) {
                throw new Error(&apos;Unkown processor priority&apos;);
            }
        }
        dataProcessorFuncs.push({
            prio: priority,
            func: processorFunc
        });
    };
    /**
     * Usage:
     * registerAction(&apos;someAction&apos;, &apos;someEvent&apos;, function () { ... });
     * registerAction(&apos;someAction&apos;, function () { ... });
     * registerAction(
     *     {type: &apos;someAction&apos;, event: &apos;someEvent&apos;, update: &apos;updateView&apos;},
     *     function () { ... }
     * );
     *
     * @param {(string|Object)} actionInfo
     * @param {string} actionInfo.type
     * @param {string} [actionInfo.event]
     * @param {string} [actionInfo.update]
     * @param {string} [eventName]
     * @param {Function} action
     */
    echarts.registerAction = function (actionInfo, eventName, action) {
        if (typeof eventName === &apos;function&apos;) {
            action = eventName;
            eventName = &apos;&apos;;
        }
        var actionType = zrUtil.isObject(actionInfo) ? actionInfo.type : [
                actionInfo,
                actionInfo = { event: eventName }
            ][0];
        // Event name is all lowercase
        actionInfo.event = (actionInfo.event || actionType).toLowerCase();
        eventName = actionInfo.event;
        if (!actions[actionType]) {
            actions[actionType] = {
                action: action,
                actionInfo: actionInfo
            };
        }
        eventActionMap[eventName] = actionType;
    };
    /**
     * @param {string} type
     * @param {*} CoordinateSystem
     */
    echarts.registerCoordinateSystem = function (type, CoordinateSystem) {
        CoordinateSystemManager.register(type, CoordinateSystem);
    };
    /**
     * Layout is a special stage of visual encoding
     * Most visual encoding like color are common for different chart
     * But each chart has it&apos;s own layout algorithm
     *
     * @param {string} [priority=1000]
     * @param {Function} layoutFunc
     */
    echarts.registerLayout = function (priority, layoutFunc) {
        if (typeof priority === &apos;function&apos;) {
            layoutFunc = priority;
            priority = PRIORITY_VISUAL_LAYOUT;
        }
        if (true) {
            if (isNaN(priority)) {
                throw new Error(&apos;Unkown layout priority&apos;);
            }
        }
        visualFuncs.push({
            prio: priority,
            func: layoutFunc,
            isLayout: true
        });
    };
    /**
     * @param {string} [priority=3000]
     * @param {Function} visualFunc
     */
    echarts.registerVisual = function (priority, visualFunc) {
        if (typeof priority === &apos;function&apos;) {
            visualFunc = priority;
            priority = PRIORITY_VISUAL_CHART;
        }
        if (true) {
            if (isNaN(priority)) {
                throw new Error(&apos;Unkown visual priority&apos;);
            }
        }
        visualFuncs.push({
            prio: priority,
            func: visualFunc
        });
    };
    var parseClassType = ComponentModel.parseClassType;
    /**
     * @param {Object} opts
     * @param {string} [superClass]
     */
    echarts.extendComponentModel = function (opts, superClass) {
        var Clazz = ComponentModel;
        if (superClass) {
            var classType = parseClassType(superClass);
            Clazz = ComponentModel.getClass(classType.main, classType.sub, true);
        }
        return Clazz.extend(opts);
    };
    /**
     * @param {Object} opts
     * @param {string} [superClass]
     */
    echarts.extendComponentView = function (opts, superClass) {
        var Clazz = ComponentView;
        if (superClass) {
            var classType = parseClassType(superClass);
            Clazz = ComponentView.getClass(classType.main, classType.sub, true);
        }
        return Clazz.extend(opts);
    };
    /**
     * @param {Object} opts
     * @param {string} [superClass]
     */
    echarts.extendSeriesModel = function (opts, superClass) {
        var Clazz = SeriesModel;
        if (superClass) {
            superClass = &apos;series.&apos; + superClass.replace(&apos;series.&apos;, &apos;&apos;);
            var classType = parseClassType(superClass);
            Clazz = SeriesModel.getClass(classType.main, classType.sub, true);
        }
        return Clazz.extend(opts);
    };
    /**
     * @param {Object} opts
     * @param {string} [superClass]
     */
    echarts.extendChartView = function (opts, superClass) {
        var Clazz = ChartView;
        if (superClass) {
            superClass.replace(&apos;series.&apos;, &apos;&apos;);
            var classType = parseClassType(superClass);
            Clazz = ChartView.getClass(classType.main, true);
        }
        return ChartView.extend(opts);
    };
    /**
     * ZRender need a canvas context to do measureText.
     * But in node environment canvas may be created by node-canvas.
     * So we need to specify how to create a canvas instead of using document.createElement(&apos;canvas&apos;)
     *
     * Be careful of using it in the browser.
     *
     * @param {Function} creator
     * @example
     *     var Canvas = require(&apos;canvas&apos;);
     *     var echarts = require(&apos;echarts&apos;);
     *     echarts.setCanvasCreator(function () {
     *         // Small size is enough.
     *         return new Canvas(32, 32);
     *     });
     */
    echarts.setCanvasCreator = function (creator) {
        zrUtil.createCanvas = creator;
    };
    echarts.registerVisual(PRIORITY_VISUAL_GLOBAL, require(&apos;./visual/seriesColor&apos;));
    echarts.registerPreprocessor(require(&apos;./preprocessor/backwardCompat&apos;));
    // Default action
    echarts.registerAction({
        type: &apos;highlight&apos;,
        event: &apos;highlight&apos;,
        update: &apos;highlight&apos;
    }, zrUtil.noop);
    echarts.registerAction({
        type: &apos;downplay&apos;,
        event: &apos;downplay&apos;,
        update: &apos;downplay&apos;
    }, zrUtil.noop);
    // --------
    // Exports
    // --------
    //
    echarts.List = require(&apos;./data/List&apos;);
    echarts.Model = require(&apos;./model/Model&apos;);
    echarts.graphic = require(&apos;./util/graphic&apos;);
    echarts.number = require(&apos;./util/number&apos;);
    echarts.format = require(&apos;./util/format&apos;);
    echarts.matrix = require(&apos;zrender/core/matrix&apos;);
    echarts.vector = require(&apos;zrender/core/vector&apos;);
    echarts.color = require(&apos;zrender/tool/color&apos;);
    echarts.util = {};
    each([
        &apos;map&apos;,
        &apos;each&apos;,
        &apos;filter&apos;,
        &apos;indexOf&apos;,
        &apos;inherits&apos;,
        &apos;reduce&apos;,
        &apos;filter&apos;,
        &apos;bind&apos;,
        &apos;curry&apos;,
        &apos;isArray&apos;,
        &apos;isString&apos;,
        &apos;isObject&apos;,
        &apos;isFunction&apos;,
        &apos;extend&apos;,
        &apos;defaults&apos;
    ], function (name) {
        echarts.util[name] = zrUtil[name];
    });
    // PRIORITY
    echarts.PRIORITY = {
        PROCESSOR: {
            FILTER: PRIORITY_PROCESSOR_FILTER,
            STATISTIC: PRIORITY_PROCESSOR_STATISTIC
        },
        VISUAL: {
            LAYOUT: PRIORITY_VISUAL_LAYOUT,
            GLOBAL: PRIORITY_VISUAL_GLOBAL,
            CHART: PRIORITY_VISUAL_CHART,
            COMPONENT: PRIORITY_VISUAL_COMPONENT,
            BRUSH: PRIORITY_VISUAL_BRUSH
        }
    };
    return echarts;
});
define(&apos;echarts/component/legend&apos;, [&apos;require&apos;, &apos;./legend/LegendModel&apos;, &apos;./legend/legendAction&apos;, &apos;./legend/LegendView&apos;, &apos;../echarts&apos;, &apos;./legend/legendFilter&apos;], function (require) {
    require(&apos;./legend/LegendModel&apos;);
    require(&apos;./legend/legendAction&apos;);
    require(&apos;./legend/LegendView&apos;);
    var echarts = require(&apos;../echarts&apos;);
    // Series Filter
    echarts.registerProcessor(require(&apos;./legend/legendFilter&apos;));
});
define(&apos;echarts/component/title&apos;, [&apos;require&apos;, &apos;../echarts&apos;, &apos;../util/graphic&apos;, &apos;../util/layout&apos;], function (require) {
    &apos;use strict&apos;;
    var echarts = require(&apos;../echarts&apos;);
    var graphic = require(&apos;../util/graphic&apos;);
    var layout = require(&apos;../util/layout&apos;);
    // Model
    echarts.extendComponentModel({
        type: &apos;title&apos;,
        layoutMode: {
            type: &apos;box&apos;,
            ignoreSize: true
        },
        defaultOption: {
            zlevel: 0,
            z: 6,
            show: true,
            text: &apos;&apos;,
            target: &apos;blank&apos;,
            subtext: &apos;&apos;,
            subtarget: &apos;blank&apos;,
            left: 0,
            top: 0,
            backgroundColor: &apos;rgba(0,0,0,0)&apos;,
            borderColor: &apos;#ccc&apos;,
            borderWidth: 0,
            padding: 5,
            itemGap: 10,
            textStyle: {
                fontSize: 18,
                fontWeight: &apos;bolder&apos;,
                color: &apos;#333&apos;
            },
            subtextStyle: { color: &apos;#aaa&apos; }
        }
    });
    // View
    echarts.extendComponentView({
        type: &apos;title&apos;,
        render: function (titleModel, ecModel, api) {
            this.group.removeAll();
            if (!titleModel.get(&apos;show&apos;)) {
                return;
            }
            var group = this.group;
            var textStyleModel = titleModel.getModel(&apos;textStyle&apos;);
            var subtextStyleModel = titleModel.getModel(&apos;subtextStyle&apos;);
            var textAlign = titleModel.get(&apos;textAlign&apos;);
            var textBaseline = titleModel.get(&apos;textBaseline&apos;);
            var textEl = new graphic.Text({
                    style: {
                        text: titleModel.get(&apos;text&apos;),
                        textFont: textStyleModel.getFont(),
                        fill: textStyleModel.getTextColor()
                    },
                    z2: 10
                });
            var textRect = textEl.getBoundingRect();
            var subText = titleModel.get(&apos;subtext&apos;);
            var subTextEl = new graphic.Text({
                    style: {
                        text: subText,
                        textFont: subtextStyleModel.getFont(),
                        fill: subtextStyleModel.getTextColor(),
                        y: textRect.height + titleModel.get(&apos;itemGap&apos;),
                        textBaseline: &apos;top&apos;
                    },
                    z2: 10
                });
            var link = titleModel.get(&apos;link&apos;);
            var sublink = titleModel.get(&apos;sublink&apos;);
            textEl.silent = !link;
            subTextEl.silent = !sublink;
            if (link) {
                textEl.on(&apos;click&apos;, function () {
                    window.open(link, &apos;_&apos; + titleModel.get(&apos;target&apos;));
                });
            }
            if (sublink) {
                subTextEl.on(&apos;click&apos;, function () {
                    window.open(sublink, &apos;_&apos; + titleModel.get(&apos;subtarget&apos;));
                });
            }
            group.add(textEl);
            subText &amp;&amp; group.add(subTextEl);
            // If no subText, but add subTextEl, there will be an empty line.
            var groupRect = group.getBoundingRect();
            var layoutOption = titleModel.getBoxLayoutParams();
            layoutOption.width = groupRect.width;
            layoutOption.height = groupRect.height;
            var layoutRect = layout.getLayoutRect(layoutOption, {
                    width: api.getWidth(),
                    height: api.getHeight()
                }, titleModel.get(&apos;padding&apos;));
            // Adjust text align based on position
            if (!textAlign) {
                // Align left if title is on the left. center and right is same
                textAlign = titleModel.get(&apos;left&apos;) || titleModel.get(&apos;right&apos;);
                if (textAlign === &apos;middle&apos;) {
                    textAlign = &apos;center&apos;;
                }
                // Adjust layout by text align
                if (textAlign === &apos;right&apos;) {
                    layoutRect.x += layoutRect.width;
                } else if (textAlign === &apos;center&apos;) {
                    layoutRect.x += layoutRect.width / 2;
                }
            }
            if (!textBaseline) {
                textBaseline = titleModel.get(&apos;top&apos;) || titleModel.get(&apos;bottom&apos;);
                if (textBaseline === &apos;center&apos;) {
                    textBaseline = &apos;middle&apos;;
                }
                if (textBaseline === &apos;bottom&apos;) {
                    layoutRect.y += layoutRect.height;
                } else if (textBaseline === &apos;middle&apos;) {
                    layoutRect.y += layoutRect.height / 2;
                }
                textBaseline = textBaseline || &apos;top&apos;;
            }
            group.attr(&apos;position&apos;, [
                layoutRect.x,
                layoutRect.y
            ]);
            var alignStyle = {
                    textAlign: textAlign,
                    textVerticalAlign: textBaseline
                };
            textEl.setStyle(alignStyle);
            subTextEl.setStyle(alignStyle);
            // Render background
            // Get groupRect again because textAlign has been changed
            groupRect = group.getBoundingRect();
            var padding = layoutRect.margin;
            var style = titleModel.getItemStyle([
                    &apos;color&apos;,
                    &apos;opacity&apos;
                ]);
            style.fill = titleModel.get(&apos;backgroundColor&apos;);
            var rect = new graphic.Rect({
                    shape: {
                        x: groupRect.x - padding[3],
                        y: groupRect.y - padding[0],
                        width: groupRect.width + padding[1] + padding[3],
                        height: groupRect.height + padding[0] + padding[2]
                    },
                    style: style,
                    silent: true
                });
            graphic.subPixelOptimizeRect(rect);
            group.add(rect);
        }
    });
});
define(&apos;echarts/component/tooltip&apos;, [&apos;require&apos;, &apos;./tooltip/TooltipModel&apos;, &apos;./tooltip/TooltipView&apos;, &apos;../echarts&apos;], function (require) {
    require(&apos;./tooltip/TooltipModel&apos;);
    require(&apos;./tooltip/TooltipView&apos;);
    // Show tip action
    /**
     * @action
     * @property {string} type
     * @property {number} seriesIndex
     * @property {number} dataIndex
     * @property {number} [x]
     * @property {number} [y]
     */
    require(&apos;../echarts&apos;).registerAction({
        type: &apos;showTip&apos;,
        event: &apos;showTip&apos;,
        update: &apos;none&apos;
    }, function () {
    });
    // Hide tip action
    require(&apos;../echarts&apos;).registerAction({
        type: &apos;hideTip&apos;,
        event: &apos;hideTip&apos;,
        update: &apos;none&apos;
    }, function () {
    });
});
define(&apos;echarts/coord/polar/polarCreator&apos;, [&apos;require&apos;, &apos;./Polar&apos;, &apos;../../util/number&apos;, &apos;../../coord/axisHelper&apos;, &apos;./PolarModel&apos;, &apos;../../CoordinateSystem&apos;], function (require) {
    var Polar = require(&apos;./Polar&apos;);
    var numberUtil = require(&apos;../../util/number&apos;);
    var axisHelper = require(&apos;../../coord/axisHelper&apos;);
    var niceScaleExtent = axisHelper.niceScaleExtent;
    // &#x4F9D;&#x8D56; PolarModel &#x505A;&#x9884;&#x5904;&#x7406;
    require(&apos;./PolarModel&apos;);
    /**
     * Resize method bound to the polar
     * @param {module:echarts/coord/polar/PolarModel} polarModel
     * @param {module:echarts/ExtensionAPI} api
     */
    function resizePolar(polarModel, api) {
        var center = polarModel.get(&apos;center&apos;);
        var radius = polarModel.get(&apos;radius&apos;);
        var width = api.getWidth();
        var height = api.getHeight();
        var parsePercent = numberUtil.parsePercent;
        this.cx = parsePercent(center[0], width);
        this.cy = parsePercent(center[1], height);
        var radiusAxis = this.getRadiusAxis();
        var size = Math.min(width, height) / 2;
        // var idx = radiusAxis.inverse ? 1 : 0;
        radiusAxis.setExtent(0, parsePercent(radius, size));
    }
    /**
     * Update polar
     */
    function updatePolarScale(ecModel, api) {
        var polar = this;
        var angleAxis = polar.getAngleAxis();
        var radiusAxis = polar.getRadiusAxis();
        // Reset scale
        angleAxis.scale.setExtent(Infinity, -Infinity);
        radiusAxis.scale.setExtent(Infinity, -Infinity);
        ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.coordinateSystem === polar) {
                var data = seriesModel.getData();
                radiusAxis.scale.unionExtent(data.getDataExtent(&apos;radius&apos;, radiusAxis.type !== &apos;category&apos;));
                angleAxis.scale.unionExtent(data.getDataExtent(&apos;angle&apos;, angleAxis.type !== &apos;category&apos;));
            }
        });
        niceScaleExtent(angleAxis, angleAxis.model);
        niceScaleExtent(radiusAxis, radiusAxis.model);
        // Fix extent of category angle axis
        if (angleAxis.type === &apos;category&apos; &amp;&amp; !angleAxis.onBand) {
            var extent = angleAxis.getExtent();
            var diff = 360 / angleAxis.scale.count();
            angleAxis.inverse ? extent[1] += diff : extent[1] -= diff;
            angleAxis.setExtent(extent[0], extent[1]);
        }
    }
    /**
     * Set common axis properties
     * @param {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}
     * @param {module:echarts/coord/polar/AxisModel}
     * @inner
     */
    function setAxis(axis, axisModel) {
        axis.type = axisModel.get(&apos;type&apos;);
        axis.scale = axisHelper.createScaleByModel(axisModel);
        axis.onBand = axisModel.get(&apos;boundaryGap&apos;) &amp;&amp; axis.type === &apos;category&apos;;
        // FIXME Radius axis not support inverse axis
        if (axisModel.mainType === &apos;angleAxis&apos;) {
            var startAngle = axisModel.get(&apos;startAngle&apos;);
            axis.inverse = axisModel.get(&apos;inverse&apos;) ^ axisModel.get(&apos;clockwise&apos;);
            axis.setExtent(startAngle, startAngle + (axis.inverse ? -360 : 360));
        }
        // Inject axis instance
        axisModel.axis = axis;
        axis.model = axisModel;
    }
    var polarCreator = {
            dimensions: Polar.prototype.dimensions,
            create: function (ecModel, api) {
                var polarList = [];
                ecModel.eachComponent(&apos;polar&apos;, function (polarModel, idx) {
                    var polar = new Polar(idx);
                    // Inject resize and update method
                    polar.resize = resizePolar;
                    polar.update = updatePolarScale;
                    var radiusAxis = polar.getRadiusAxis();
                    var angleAxis = polar.getAngleAxis();
                    var radiusAxisModel = polarModel.findAxisModel(&apos;radiusAxis&apos;);
                    var angleAxisModel = polarModel.findAxisModel(&apos;angleAxis&apos;);
                    setAxis(radiusAxis, radiusAxisModel);
                    setAxis(angleAxis, angleAxisModel);
                    polar.resize(polarModel, api);
                    polarList.push(polar);
                    polarModel.coordinateSystem = polar;
                });
                // Inject coordinateSystem to series
                ecModel.eachSeries(function (seriesModel) {
                    if (seriesModel.get(&apos;coordinateSystem&apos;) === &apos;polar&apos;) {
                        seriesModel.coordinateSystem = polarList[seriesModel.get(&apos;polarIndex&apos;)];
                    }
                });
                return polarList;
            }
        };
    require(&apos;../../CoordinateSystem&apos;).register(&apos;polar&apos;, polarCreator);
});
define(&apos;echarts/component/angleAxis&apos;, [&apos;require&apos;, &apos;../coord/polar/polarCreator&apos;, &apos;./axis/AngleAxisView&apos;], function (require) {
    &apos;use strict&apos;;
    require(&apos;../coord/polar/polarCreator&apos;);
    require(&apos;./axis/AngleAxisView&apos;);
});
define(&apos;echarts/scale/Time&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../util/number&apos;, &apos;../util/format&apos;, &apos;./Interval&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var numberUtil = require(&apos;../util/number&apos;);
    var formatUtil = require(&apos;../util/format&apos;);
    var IntervalScale = require(&apos;./Interval&apos;);
    var intervalScaleProto = IntervalScale.prototype;
    var mathCeil = Math.ceil;
    var mathFloor = Math.floor;
    var ONE_SECOND = 1000;
    var ONE_MINUTE = ONE_SECOND * 60;
    var ONE_HOUR = ONE_MINUTE * 60;
    var ONE_DAY = ONE_HOUR * 24;
    // FIXME &#x516C;&#x7528;&#xFF1F;
    var bisect = function (a, x, lo, hi) {
        while (lo &lt; hi) {
            var mid = lo + hi &gt;&gt;&gt; 1;
            if (a[mid][2] &lt; x) {
                lo = mid + 1;
            } else {
                hi = mid;
            }
        }
        return lo;
    };
    /**
     * @alias module:echarts/coord/scale/Time
     * @constructor
     */
    var TimeScale = IntervalScale.extend({
            type: &apos;time&apos;,
            getLabel: function (val) {
                var stepLvl = this._stepLvl;
                var date = new Date(val);
                return formatUtil.formatTime(stepLvl[0], date);
            },
            niceExtent: function (approxTickNum, fixMin, fixMax) {
                var extent = this._extent;
                // If extent start and end are same, expand them
                if (extent[0] === extent[1]) {
                    // Expand extent
                    extent[0] -= ONE_DAY;
                    extent[1] += ONE_DAY;
                }
                // If there are no data and extent are [Infinity, -Infinity]
                if (extent[1] === -Infinity &amp;&amp; extent[0] === Infinity) {
                    var d = new Date();
                    extent[1] = new Date(d.getFullYear(), d.getMonth(), d.getDate());
                    extent[0] = extent[1] - ONE_DAY;
                }
                this.niceTicks(approxTickNum);
                // var extent = this._extent;
                var interval = this._interval;
                if (!fixMin) {
                    extent[0] = numberUtil.round(mathFloor(extent[0] / interval) * interval);
                }
                if (!fixMax) {
                    extent[1] = numberUtil.round(mathCeil(extent[1] / interval) * interval);
                }
            },
            niceTicks: function (approxTickNum) {
                approxTickNum = approxTickNum || 10;
                var extent = this._extent;
                var span = extent[1] - extent[0];
                var approxInterval = span / approxTickNum;
                var scaleLevelsLen = scaleLevels.length;
                var idx = bisect(scaleLevels, approxInterval, 0, scaleLevelsLen);
                var level = scaleLevels[Math.min(idx, scaleLevelsLen - 1)];
                var interval = level[2];
                // Same with interval scale if span is much larger than 1 year
                if (level[0] === &apos;year&apos;) {
                    var yearSpan = span / interval;
                    // From &quot;Nice Numbers for Graph Labels&quot; of Graphic Gems
                    // var niceYearSpan = numberUtil.nice(yearSpan, false);
                    var yearStep = numberUtil.nice(yearSpan / approxTickNum, true);
                    interval *= yearStep;
                }
                var niceExtent = [
                        mathCeil(extent[0] / interval) * interval,
                        mathFloor(extent[1] / interval) * interval
                    ];
                this._stepLvl = level;
                // Interval will be used in getTicks
                this._interval = interval;
                this._niceExtent = niceExtent;
            },
            parse: function (val) {
                // val might be float.
                return +numberUtil.parseDate(val);
            }
        });
    zrUtil.each([
        &apos;contain&apos;,
        &apos;normalize&apos;
    ], function (methodName) {
        TimeScale.prototype[methodName] = function (val) {
            return intervalScaleProto[methodName].call(this, this.parse(val));
        };
    });
    // Steps from d3
    var scaleLevels = [
            [
                &apos;hh:mm:ss&apos;,
                1,
                ONE_SECOND
            ],
            [
                &apos;hh:mm:ss&apos;,
                5,
                ONE_SECOND * 5
            ],
            [
                &apos;hh:mm:ss&apos;,
                10,
                ONE_SECOND * 10
            ],
            [
                &apos;hh:mm:ss&apos;,
                15,
                ONE_SECOND * 15
            ],
            [
                &apos;hh:mm:ss&apos;,
                30,
                ONE_SECOND * 30
            ],
            [
                &apos;hh:mm\nMM-dd&apos;,
                1,
                ONE_MINUTE
            ],
            [
                &apos;hh:mm\nMM-dd&apos;,
                5,
                ONE_MINUTE * 5
            ],
            [
                &apos;hh:mm\nMM-dd&apos;,
                10,
                ONE_MINUTE * 10
            ],
            [
                &apos;hh:mm\nMM-dd&apos;,
                15,
                ONE_MINUTE * 15
            ],
            [
                &apos;hh:mm\nMM-dd&apos;,
                30,
                ONE_MINUTE * 30
            ],
            [
                &apos;hh:mm\nMM-dd&apos;,
                1,
                ONE_HOUR
            ],
            [
                &apos;hh:mm\nMM-dd&apos;,
                2,
                ONE_HOUR * 2
            ],
            [
                &apos;hh:mm\nMM-dd&apos;,
                6,
                ONE_HOUR * 6
            ],
            [
                &apos;hh:mm\nMM-dd&apos;,
                12,
                ONE_HOUR * 12
            ],
            [
                &apos;MM-dd\nyyyy&apos;,
                1,
                ONE_DAY
            ],
            [
                &apos;week&apos;,
                7,
                ONE_DAY * 7
            ],
            [
                &apos;month&apos;,
                1,
                ONE_DAY * 31
            ],
            [
                &apos;quarter&apos;,
                3,
                ONE_DAY * 380 / 4
            ],
            [
                &apos;half-year&apos;,
                6,
                ONE_DAY * 380 / 2
            ],
            [
                &apos;year&apos;,
                1,
                ONE_DAY * 380
            ]
        ];
    /**
     * @return {module:echarts/scale/Time}
     */
    TimeScale.create = function () {
        return new TimeScale();
    };
    return TimeScale;
});
define(&apos;echarts/scale/Log&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;./Scale&apos;, &apos;../util/number&apos;, &apos;./Interval&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var Scale = require(&apos;./Scale&apos;);
    var numberUtil = require(&apos;../util/number&apos;);
    // Use some method of IntervalScale
    var IntervalScale = require(&apos;./Interval&apos;);
    var scaleProto = Scale.prototype;
    var intervalScaleProto = IntervalScale.prototype;
    var mathFloor = Math.floor;
    var mathCeil = Math.ceil;
    var mathPow = Math.pow;
    var LOG_BASE = 10;
    var mathLog = Math.log;
    var LogScale = Scale.extend({
            type: &apos;log&apos;,
            getTicks: function () {
                return zrUtil.map(intervalScaleProto.getTicks.call(this), function (val) {
                    return numberUtil.round(mathPow(LOG_BASE, val));
                });
            },
            getLabel: intervalScaleProto.getLabel,
            scale: function (val) {
                val = scaleProto.scale.call(this, val);
                return mathPow(LOG_BASE, val);
            },
            setExtent: function (start, end) {
                start = mathLog(start) / mathLog(LOG_BASE);
                end = mathLog(end) / mathLog(LOG_BASE);
                intervalScaleProto.setExtent.call(this, start, end);
            },
            getExtent: function () {
                var extent = scaleProto.getExtent.call(this);
                extent[0] = mathPow(LOG_BASE, extent[0]);
                extent[1] = mathPow(LOG_BASE, extent[1]);
                return extent;
            },
            unionExtent: function (extent) {
                extent[0] = mathLog(extent[0]) / mathLog(LOG_BASE);
                extent[1] = mathLog(extent[1]) / mathLog(LOG_BASE);
                scaleProto.unionExtent.call(this, extent);
            },
            niceTicks: function (approxTickNum) {
                approxTickNum = approxTickNum || 10;
                var extent = this._extent;
                var span = extent[1] - extent[0];
                if (span === Infinity || span <= 0="" 1="" 2="" 10="" 0)="" {="" return;="" }="" var="" interval="mathPow(10," mathfloor(mathlog(span="" approxticknum)="" math.ln10));="" err="approxTickNum" span="" *="" interval;="" filter="" ticks="" to="" get="" closer="" the="" desired="" count.="" if="" (err="" <="0.5)" niceextent="[" numberutil.round(mathceil(extent[0]="" interval)="" interval),="" numberutil.round(mathfloor(extent[1]="" ];="" this._interval="interval;" this._niceextent="niceExtent;" },="" niceextent:="" intervalscaleproto.niceextent="" });="" zrutil.each([="" 'contain',="" 'normalize'="" ],="" function="" (methodname)="" logscale.prototype[methodname]="function" (val)="" val="mathLog(val)" mathlog(log_base);="" return="" scaleproto[methodname].call(this,="" val);="" };="" logscale.create="function" ()="" new="" logscale();="" logscale;="" define('echarts="" component="" radiusaxis',="" ['require',="" '..="" coord="" polar="" polarcreator',="" '.="" axis="" radiusaxisview'],="" (require)="" require('..="" polarcreator');="" require('.="" radiusaxisview');="" define('zrender="" core="" util',="" ['require'],="" 用于处理merge时无法遍历date等对象的问题="" builtin_object="{" '[object="" function]':="" 1,="" regexp]':="" date]':="" error]':="" canvasgradient]':="" canvaspattern]':="" image]':="" objtostring="Object.prototype.toString;" arrayproto="Array.prototype;" nativeforeach="arrayProto.forEach;" nativefilter="arrayProto.filter;" nativeslice="arrayProto.slice;" nativemap="arrayProto.map;" nativereduce="arrayProto.reduce;" **="" @param="" {*}="" source="" @return="" 拷贝后的新对象="" clone(source)="" (typeof="" 'object'="" &&="" !="=" null)="" result="source;" (source="" instanceof="" array)="" for="" (var="" i="0," len="source.length;" len;="" i++)="" result[i]="clone(source[i]);" else="" (!isbuildinobject(source)="" !isdom(source))="" key="" in="" source)="" (source.hasownproperty(key))="" result[key]="clone(source[key]);" result;="" source;="" @memberof="" module:zrender="" util="" target="" {boolean}="" [overwrite="false]" merge(target,="" source,="" overwrite)="" we="" should="" escapse="" that="" is="" string="" and="" enter="" ...="" (!isobject(source)="" ||="" !isobject(target))="" overwrite="" ?="" :="" target;="" targetprop="target[key];" sourceprop="source[key];" (isobject(sourceprop)="" isobject(targetprop)="" !isarray(sourceprop)="" !isarray(targetprop)="" !isdom(sourceprop)="" !isdom(targetprop)="" !isbuildinobject(sourceprop)="" !isbuildinobject(targetprop))="" 如果需要递归覆盖，就递归调用merge="" merge(targetprop,="" sourceprop,="" overwrite);="" (overwrite="" !(key="" target))="" 否则只处理overwrite为true，或者在目标对象中没有此属性的情况="" note，在="" target[key]="" 不存在的时候也是直接覆盖="" true);="" {array}="" targetandsources="" first="" item="" target,="" rests="" are="" source.="" mergeall(targetandsources,="" targetandsources[i],="" extend(target,="" {boolen}="" [overlay="false]" defaults(target,="" overlay)="" (source.hasownproperty(key)="" (overlay="" source[key]="" null))="" createcanvas()="" document.createelement('canvas');="" fixme="" _ctx;="" getcontext()="" (!_ctx)="" use="" util.createcanvas="" instead="" of="" createcanvas="" because="" may="" be="" overwritten="" different="" environment="" _ctx="util.createCanvas().getContext(&apos;2d&apos;);" 查询数组中元素的index="" indexof(array,="" value)="" (array)="" (array.indexof)="" array.indexof(value);="" (array[i]="==" i;="" -1;="" 构造类继承关系="" {function}="" clazz="" 源类="" baseclazz="" 基类="" inherits(clazz,="" baseclazz)="" clazzprototype="clazz.prototype;" f()="" f.prototype="baseClazz.prototype;" clazz.prototype="new" f();="" prop="" clazzprototype)="" clazz.prototype[prop]="clazzPrototype[prop];" clazz.prototype.constructor="clazz;" clazz.superclass="baseClazz;" {object|function}="" sorce="" overlay="" mixin(target,="" target.prototype="" source.prototype="" overlay);="" {array|typedarray}="" data="" isarraylike(data)="" (!data)="" 'string')="" false;="" typeof="" data.length="=" 'number';="" 数组或对象遍历="" {object|array}="" obj="" cb="" [context]="" each(obj,="" cb,="" context)="" (!(obj="" cb))="" (obj.foreach="" obj.foreach="==" nativeforeach)="" obj.foreach(cb,="" context);="" (obj.length="==" +obj.length)="" cb.call(context,="" obj[i],="" i,="" obj);="" obj)="" (obj.hasownproperty(key))="" obj[key],="" key,="" 数组映射="" map(obj,="" (obj.map="" obj.map="==" nativemap)="" obj.map(cb,="" result.push(cb.call(context,="" obj));="" {object}="" [memo]="" reduce(obj,="" memo,="" (obj.reduce="" obj.reduce="==" nativereduce)="" obj.reduce(cb,="" memo="cb.call(context," memo;="" 数组过滤="" filter(obj,="" (obj.filter="" obj.filter="==" nativefilter)="" obj.filter(cb,="" (cb.call(context,="" obj))="" result.push(obj[i]);="" 数组项查找="" find(obj,="" obj[i];="" func="" context="" bind(func,="" args="nativeSlice.call(arguments," 2);="" func.apply(context,="" args.concat(nativeslice.call(arguments)));="" curry(func)="" 1);="" func.apply(this,="" value="" isarray(value)="" objtostring.call(value)="==" array]';="" isfunction(value)="" 'function';="" isstring(value)="" string]';="" isobject(value)="" avoid="" a="" v8="" jit="" bug="" chrome="" 19-20.="" see="" https:="" code.google.com="" p="" issues="" detail?id="2291" more="" details.="" type="typeof" value;="" 'function'="" !!value="" 'object';="" isbuildinobject(value)="" !!builtin_object[objtostring.call(value)];="" isdom(value)="" value.nodetype="==" value.nodename="=" 'string';="" value1="" not="" null,="" then="" value1,="" otherwise="" judget="" rest="" values.="" final="" retrieve(values)="" (arguments[i]="" arguments[i];="" arr="" {number}="" startindex="" endindex="" slice()="" function.call.apply(nativeslice,="" arguments);="" condition="" {string}="" message="" assert(condition,="" message)="" (!condition)="" throw="" error(message);="" inherits:="" inherits,="" mixin:="" mixin,="" clone:="" clone,="" merge:="" merge,="" mergeall:="" mergeall,="" extend:="" extend,="" defaults:="" defaults,="" getcontext:="" getcontext,="" createcanvas:="" createcanvas,="" indexof:="" indexof,="" slice:="" slice,="" find:="" find,="" isarraylike:="" isarraylike,="" each:="" each,="" map:="" map,="" reduce:="" reduce,="" filter:="" filter,="" bind:="" bind,="" curry:="" curry,="" isarray:="" isarray,="" isstring:="" isstring,="" isobject:="" isobject,="" isfunction:="" isfunction,="" isbuildinobject:="" isbuildinobject,="" isdom:="" isdom,="" retrieve:="" retrieve,="" assert:="" assert,="" noop:="" util;="" chart="" pie="" pieseries',="" ..="" list',="" 'zrender="" model',="" helper="" completedimensions',="" selectablemixin',="" echarts'],="" 'use="" strict';="" list="require(&apos;../../data/List&apos;);" zrutil="require(&apos;zrender/core/util&apos;);" modelutil="require(&apos;../../util/model&apos;);" completedimensions="require(&apos;../../data/helper/completeDimensions&apos;);" dataselectablemixin="require(&apos;../../component/helper/selectableMixin&apos;);" pieseries="require(&apos;../../echarts&apos;).extendSeriesModel({" type:="" 'series.pie',="" init:="" (option)="" pieseries.superapply(this,="" 'init',="" enable="" legend="" selection="" each="" direct="" access="" reference="" changed="" this.legenddataprovider="function" this._databeforeprocessed;="" this.updateselectedmap(option.data);="" this._defaultlabelline(option);="" mergeoption:="" (newoption)="" pieseries.supercall(this,="" 'mergeoption',="" newoption);="" this.updateselectedmap(this.option.data);="" getinitialdata:="" (option,="" ecmodel)="" dimensions="completeDimensions([&apos;value&apos;]," option.data);="" list(dimensions,="" this);="" list.initdata(option.data);="" list;="" getdataparams:="" (dataindex)="" params="PieSeries.superCall(this," 'getdataparams',="" dataindex);="" sum="data.getSum(&apos;value&apos;);" tofixed?="" percent="" params.percent="!sum" +(data.get('value',="" dataindex)="" 100).tofixed(2);="" params.$vars.push('percent');="" params;="" _defaultlabelline:="" extend="" labelline="" emphasis="" modelutil.defaultemphasis(option.labelline,="" ['show']);="" labellinenormalopt="option.labelLine.normal;" labellineemphasisopt="option.labelLine.emphasis;" show="" label="" line="" `label.normal.show="false`" labellinenormalopt.show="labelLineNormalOpt.show" option.label.normal.show;="" labellineemphasisopt.show="labelLineEmphasisOpt.show" option.label.emphasis.show;="" defaultoption:="" zlevel:="" 0,="" z:="" 2,="" legendhoverlink:="" true,="" hoveranimation:="" center:="" [="" '50%',="" '50%'="" radius:="" '75%'="" clockwise:="" startangle:="" 90,="" minangle:="" selectedoffset:="" 10,="" avoidlabeloverlap:="" label:="" normal:="" rotate:="" false,="" show:="" position:="" 'outer'="" emphasis:="" {}="" labelline:="" length:="" 15,="" length2:="" smooth:="" linestyle:="" width:="" 'solid'="" itemstyle:="" borderwidth:="" animationeasing:="" 'cubicout',="" data:="" []="" zrutil.mixin(pieseries,="" dataselectablemixin);="" pieseries;="" pieview',="" graphic',="" view="" chart'],="" graphic="require(&apos;../../util/graphic&apos;);" {module:echarts="" model="" series}="" seriesmodel="" hasanimation="" @inner="" updatedataselected(uid,="" seriesmodel,="" hasanimation,="" api)="" dataindex="this.dataIndex;" name="data.getName(dataIndex);" selectedoffset="seriesModel.get(&apos;selectedOffset&apos;);" api.dispatchaction({="" 'pietoggleselect',="" from:="" uid,="" name:="" name,="" seriesid:="" seriesmodel.id="" data.each(function="" (idx)="" toggleitemselected(data.getitemgraphicel(idx),="" data.getitemlayout(idx),="" seriesmodel.isselected(data.getname(idx)),="" selectedoffset,="" hasanimation);="" {module:zrender="" sector}="" el="" layout="" isselected="" toggleitemselected(el,="" layout,="" isselected,="" hasanimation)="" midangle="(layout.startAngle" +="" layout.endangle)="" 2;="" dx="Math.cos(midAngle);" dy="Math.sin(midAngle);" offset="isSelected" 0;="" position="[" offset,="" el.animate().when(200,="" }).start('bounceout')="" el.attr('position',="" position);="" piece="" including="" sector,="" label,="" @constructor="" @extends="" group}="" piepiece(data,="" idx)="" graphic.group.call(this);="" sector="new" graphic.sector({="" z2:="" polyline="new" graphic.polyline();="" text="new" graphic.text();="" this.add(sector);="" this.add(polyline);="" this.add(text);="" this.updatedata(data,="" idx,="" hover="" change="" onemphasis()="" polyline.ignore="polyline.hoverIgnore;" text.ignore="text.hoverIgnore;" onnormal()="" this.on('emphasis',="" onemphasis).on('normal',="" onnormal).on('mouseover',="" onemphasis).on('mouseout',="" onnormal);="" piepieceproto="PiePiece.prototype;" getlabelstyle(data,="" state,="" labelmodel,="" labelposition)="" textstylemodel="labelModel.getModel(&apos;textStyle&apos;);" islabelinside="labelPosition" =="=" 'inside'="" labelposition="==" 'inner';="" fill:="" textstylemodel.gettextcolor()="" (islabelinside="" '#fff'="" data.getitemvisual(idx,="" 'color')),="" opacity:="" 'opacity'),="" textfont:="" textstylemodel.getfont(),="" text:="" zrutil.retrieve(data.hostmodel.getformattedlabel(idx,="" state),="" data.getname(idx))="" piepieceproto.updatedata="function" (data,="" firstcreate)="" itemmodel="data.getItemModel(idx);" sectorshape="zrUtil.extend({}," layout);="" sectorshape.label="null;" (firstcreate)="" sector.setshape(sectorshape);="" sector.shape.endangle="layout.startAngle;" graphic.updateprops(sector,="" shape:="" endangle:="" layout.endangle="" idx);="" update="" common="" style="" itemstylemodel="itemModel.getModel(&apos;itemStyle&apos;);" visualcolor="data.getItemVisual(idx," 'color');="" sector.usestyle(zrutil.defaults({="" linejoin:="" 'bevel',="" itemstylemodel.getmodel('normal').getitemstyle()));="" sector.hoverstyle="itemStyleModel.getModel(&apos;emphasis&apos;).getItemStyle();" toggle="" selected toggleitemselected(this,="" itemmodel.get('selected'),="" seriesmodel.get('selectedoffset'),="" seriesmodel.get('animation'));="" has="" animation="" updating="" data.="" force="" move="" last="" frame="" or="" it="" stopped="" on="" wrong="" shape="" sector.stopanimation(true);="" sector.animateto({="" r:="" layout.r="" 300,="" 'elasticout');="" sector.off('mouseover').off('mouseout').off('emphasis').off('normal');="" (itemmodel.get('hoveranimation')="" seriesmodel.ifenableanimation())="" sector.on('mouseover',="" onnormal).on('emphasis',="" this._updatelabel(data,="" graphic.sethoverstyle(this);="" piepieceproto._updatelabel="function" labeltext="this.childAt(2);" labellayout="layout.label;" graphic.updateprops(labelline,="" points:="" labellayout.linepoints="" labellayout.x,="" labellayout.y="" ]="" graphic.updateprops(labeltext,="" style:="" x:="" y:="" labeltext.attr({="" textverticalalign:="" labellayout.verticalalign,="" textalign:="" labellayout.textalign,="" labellayout.font="" rotation:="" labellayout.rotation,="" origin:="" labelmodel="itemModel.getModel(&apos;label.normal&apos;);" labelhovermodel="itemModel.getModel(&apos;label.emphasis&apos;);" labellinemodel="itemModel.getModel(&apos;labelLine.normal&apos;);" labellinehovermodel="itemModel.getModel(&apos;labelLine.emphasis&apos;);" labelhovermodel.get('position');="" labeltext.setstyle(getlabelstyle(data,="" 'normal',="" labelposition));="" labeltext.ignore="labelText.normalIgnore" !labelmodel.get('show');="" labeltext.hoverignore="!labelHoverModel.get(&apos;show&apos;);" labelline.ignore="labelLine.normalIgnore" !labellinemodel.get('show');="" labelline.hoverignore="!labelLineHoverModel.get(&apos;show&apos;);" default visual="" color="" labelline.setstyle({="" stroke:="" visualcolor,="" 'opacity')="" labelline.setstyle(labellinemodel.getmodel('linestyle').getlinestyle());="" labeltext.hoverstyle="getLabelStyle(data," 'emphasis',="" labelhovermodel,="" labelposition);="" labelline.hoverstyle="labelLineHoverModel.getModel(&apos;lineStyle&apos;).getLineStyle();" smooth="labelLineModel.get(&apos;smooth&apos;);" (smooth="" true)="" labelline.setshape({="" zrutil.inherits(piepiece,="" graphic.group);="" 'pie',="" sectorgroup="new" graphic.group();="" this._sectorgroup="sectorGroup;" render:="" (seriesmodel,="" ecmodel,="" api,="" payload)="" (payload="" payload.from="==" this.uid)="" olddata="this._data;" group="this.group;" isfirstrender="!oldData;" onsectorclick="zrUtil.curry(updateDataSelected," this.uid,="" api);="" selectedmode="seriesModel.get(&apos;selectedMode&apos;);" data.diff(olddata).add(function="" piepiece="new" (isfirstrender)="" piepiece.eachchild(function="" (child)="" child.stopanimation(true);="" piepiece.on('click',="" onsectorclick);="" data.setitemgraphicel(idx,="" piepiece);="" group.add(piepiece);="" }).update(function="" (newidx,="" oldidx)="" piepiece.updatedata(data,="" newidx);="" piepiece.off('click');="" data.setitemgraphicel(newidx,="" }).remove(function="" group.remove(piepiece);="" }).execute();="" (hasanimation="" data.count()=""> 0) {
                    var shape = data.getItemLayout(0);
                    var r = Math.max(api.getWidth(), api.getHeight()) / 2;
                    var removeClipPath = zrUtil.bind(group.removeClipPath, group);
                    group.setClipPath(this._createClipPath(shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath, seriesModel));
                }
                this._data = data;
            },
            _createClipPath: function (cx, cy, r, startAngle, clockwise, cb, seriesModel) {
                var clipPath = new graphic.Sector({
                        shape: {
                            cx: cx,
                            cy: cy,
                            r0: 0,
                            r: r,
                            startAngle: startAngle,
                            endAngle: startAngle,
                            clockwise: clockwise
                        }
                    });
                graphic.initProps(clipPath, { shape: { endAngle: startAngle + (clockwise ? 1 : -1) * Math.PI * 2 } }, seriesModel, cb);
                return clipPath;
            }
        });
    return Pie;
});
define(&apos;echarts/visual/dataColor&apos;, [&apos;require&apos;], function (require) {
    return function (seriesType, ecModel) {
        // Pie and funnel may use diferrent scope
        var paletteScope = {};
        ecModel.eachRawSeriesByType(seriesType, function (seriesModel) {
            var dataAll = seriesModel.getRawData();
            var idxMap = {};
            if (!ecModel.isSeriesFiltered(seriesModel)) {
                var data = seriesModel.getData();
                data.each(function (idx) {
                    var rawIdx = data.getRawIndex(idx);
                    idxMap[rawIdx] = idx;
                });
                dataAll.each(function (rawIdx) {
                    // FIXME Performance
                    var itemModel = dataAll.getItemModel(rawIdx);
                    var filteredIdx = idxMap[rawIdx];
                    // If series.itemStyle.normal.color is a function. itemVisual may be encoded
                    var singleDataColor = data.getItemVisual(filteredIdx, &apos;color&apos;, true);
                    if (!singleDataColor) {
                        var color = itemModel.get(&apos;itemStyle.normal.color&apos;) || seriesModel.getColorFromPalette(dataAll.getName(rawIdx), paletteScope);
                        // Legend may use the visual info in data before processed
                        dataAll.setItemVisual(rawIdx, &apos;color&apos;, color);
                        data.setItemVisual(filteredIdx, &apos;color&apos;, color);
                    } else {
                        // Set data all color for legend
                        dataAll.setItemVisual(rawIdx, &apos;color&apos;, singleDataColor);
                    }
                });
            }
        });
    };
});
define(&apos;echarts/chart/pie/pieLayout&apos;, [&apos;require&apos;, &apos;../../util/number&apos;, &apos;./labelLayout&apos;, &apos;zrender/core/util&apos;], function (require) {
    var numberUtil = require(&apos;../../util/number&apos;);
    var parsePercent = numberUtil.parsePercent;
    var labelLayout = require(&apos;./labelLayout&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var PI2 = Math.PI * 2;
    var RADIAN = Math.PI / 180;
    return function (seriesType, ecModel, api, payload) {
        ecModel.eachSeriesByType(seriesType, function (seriesModel) {
            var center = seriesModel.get(&apos;center&apos;);
            var radius = seriesModel.get(&apos;radius&apos;);
            if (!zrUtil.isArray(radius)) {
                radius = [
                    0,
                    radius
                ];
            }
            if (!zrUtil.isArray(center)) {
                center = [
                    center,
                    center
                ];
            }
            var width = api.getWidth();
            var height = api.getHeight();
            var size = Math.min(width, height);
            var cx = parsePercent(center[0], width);
            var cy = parsePercent(center[1], height);
            var r0 = parsePercent(radius[0], size / 2);
            var r = parsePercent(radius[1], size / 2);
            var data = seriesModel.getData();
            var startAngle = -seriesModel.get(&apos;startAngle&apos;) * RADIAN;
            var minAngle = seriesModel.get(&apos;minAngle&apos;) * RADIAN;
            var sum = data.getSum(&apos;value&apos;);
            // Sum may be 0
            var unitRadian = Math.PI / (sum || data.count()) * 2;
            var clockwise = seriesModel.get(&apos;clockwise&apos;);
            var roseType = seriesModel.get(&apos;roseType&apos;);
            // [0...max]
            var extent = data.getDataExtent(&apos;value&apos;);
            extent[0] = 0;
            // In the case some sector angle is smaller than minAngle
            var restAngle = PI2;
            var valueSumLargerThanMinAngle = 0;
            var currentAngle = startAngle;
            var dir = clockwise ? 1 : -1;
            data.each(&apos;value&apos;, function (value, idx) {
                var angle;
                // FIXME &#x517C;&#x5BB9; 2.0 &#x4F46;&#x662F; roseType &#x662F; area &#x7684;&#x65F6;&#x5019;&#x624D;&#x662F;&#x8FD9;&#x6837;&#xFF1F;
                if (roseType !== &apos;area&apos;) {
                    angle = sum === 0 ? unitRadian : value * unitRadian;
                } else {
                    angle = PI2 / (data.count() || 1);
                }
                if (angle &lt; minAngle) {
                    angle = minAngle;
                    restAngle -= minAngle;
                } else {
                    valueSumLargerThanMinAngle += value;
                }
                var endAngle = currentAngle + dir * angle;
                data.setItemLayout(idx, {
                    angle: angle,
                    startAngle: currentAngle,
                    endAngle: endAngle,
                    clockwise: clockwise,
                    cx: cx,
                    cy: cy,
                    r0: r0,
                    r: roseType ? numberUtil.linearMap(value, extent, [
                        r0,
                        r
                    ]) : r
                });
                currentAngle = endAngle;
            }, true);
            // Some sector is constrained by minAngle
            // Rest sectors needs recalculate angle
            if (restAngle &lt; PI2) {
                // Average the angle if rest angle is not enough after all angles is
                // Constrained by minAngle
                if (restAngle <= 0.001)="" {="" var="" angle="PI2" data.count();="" data.each(function="" (idx)="" layout="data.getItemLayout(idx);" layout.startangle="startAngle" +="" dir="" *="" idx="" angle;="" layout.endangle="startAngle" (idx="" 1)="" });="" }="" else="" unitradian="restAngle" valuesumlargerthanminangle;="" currentangle="startAngle;" data.each('value',="" function="" (value,="" idx)="" =="=" minangle="" ?="" :="" value="" unitradian;="" labellayout(seriesmodel,="" r,="" width,="" height);="" };="" define('echarts="" processor="" datafilter',="" [],="" ()="" return="" (seriestype,="" ecmodel)="" legendmodels="ecModel.findComponents({" maintype:="" 'legend'="" if="" (!legendmodels="" ||="" !legendmodels.length)="" return;="" ecmodel.eachseriesbytype(seriestype,="" (series)="" data="series.getData();" data.filterself(function="" name="data.getName(idx);" in="" any="" legend="" component="" the="" status="" is="" not="" selected.="" for="" (var="" i="0;" <="" legendmodels.length;="" i++)="" (!legendmodels[i].isselected(name))="" false;="" true;="" },="" this);="" visual="" symbol',="" ['require'],="" (require)="" defaultsymboltype,="" legendsymbol,="" ecmodel,="" api)="" encoding="" all="" series="" include="" which="" filtered="" drawing="" ecmodel.eachrawseriesbytype(seriestype,="" (seriesmodel)="" symboltype="seriesModel.get(&apos;symbol&apos;)" defaultsymboltype;="" symbolsize="seriesModel.get(&apos;symbolSize&apos;);" data.setvisual({="" legendsymbol:="" legendsymbol="" symboltype,="" symbol:="" symbolsize:="" only="" visible="" has="" each="" be="" encoded="" (!ecmodel.isseriesfiltered(seriesmodel))="" (typeof="" 'function')="" rawvalue="seriesModel.getRawValue(idx);" fixme="" params="seriesModel.getDataParams(idx);" data.setitemvisual(idx,="" 'symbolsize',="" symbolsize(rawvalue,="" params));="" itemmodel="data.getItemModel(idx);" itemsymboltype="itemModel.getShallow(&apos;symbol&apos;," true);="" itemsymbolsize="itemModel.getShallow(&apos;symbolSize&apos;," item="" symbol="" (itemsymboltype="" !="null)" 'symbol',="" itemsymboltype);="" (itemsymbolsize="" pending="" transform="" itemsymbolsize);="" chart="" radar="" radarseries',="" ['require',="" '..="" ..="" model="" series',="" list',="" helper="" completedimensions',="" 'zrender="" core="" util'],="" 'use="" strict';="" seriesmodel="require(&apos;../../model/Series&apos;);" list="require(&apos;../../data/List&apos;);" completedimensions="require(&apos;../../data/helper/completeDimensions&apos;);" zrutil="require(&apos;zrender/core/util&apos;);" radarseries="SeriesModel.extend({" type:="" 'series.radar',="" dependencies:="" ['radar'],="" init:="" (option)="" radarseries.superapply(this,="" 'init',="" arguments);="" enable="" selection="" use="" a="" instead="" of="" direct="" access="" because="" reference="" may="" changed="" this.legenddataprovider="function" this._databeforeprocessed;="" getinitialdata:="" (option,="" [];="" dimensions="completeDimensions([]," data,="" 'indicator_');="" list(dimensions,="" list.initdata(data);="" list;="" formattooltip:="" (dataindex)="" coordsys="this.coordinateSystem;" indicatoraxes="coordSys.getIndicatorAxes();" (this._data.getname(dataindex)="=" ''="" this.name="" this._data.getname(dataindex))="" '<br="">&apos; + zrUtil.map(indicatorAxes, function (axis, idx) {
                    return axis.name + &apos; : &apos; + value[idx];
                }).join(&apos;<br>&apos;);
            },
            defaultOption: {
                zlevel: 0,
                z: 2,
                coordinateSystem: &apos;radar&apos;,
                legendHoverLink: true,
                radarIndex: 0,
                lineStyle: {
                    normal: {
                        width: 2,
                        type: &apos;solid&apos;
                    }
                },
                label: { normal: { position: &apos;top&apos; } },
                symbol: &apos;emptyCircle&apos;,
                symbolSize: 4
            }
        });
    return RadarSeries;
});
define(&apos;echarts/chart/radar/RadarView&apos;, [&apos;require&apos;, &apos;../../util/graphic&apos;, &apos;zrender/core/util&apos;, &apos;../../util/symbol&apos;, &apos;../../echarts&apos;], function (require) {
    var graphic = require(&apos;../../util/graphic&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var symbolUtil = require(&apos;../../util/symbol&apos;);
    function normalizeSymbolSize(symbolSize) {
        if (!zrUtil.isArray(symbolSize)) {
            symbolSize = [
                +symbolSize,
                +symbolSize
            ];
        }
        return symbolSize;
    }
    return require(&apos;../../echarts&apos;).extendChartView({
        type: &apos;radar&apos;,
        render: function (seriesModel, ecModel, api) {
            var polar = seriesModel.coordinateSystem;
            var group = this.group;
            var data = seriesModel.getData();
            var oldData = this._data;
            function createSymbol(data, idx) {
                var symbolType = data.getItemVisual(idx, &apos;symbol&apos;) || &apos;circle&apos;;
                var color = data.getItemVisual(idx, &apos;color&apos;);
                if (symbolType === &apos;none&apos;) {
                    return;
                }
                var symbolPath = symbolUtil.createSymbol(symbolType, -0.5, -0.5, 1, 1, color);
                symbolPath.attr({
                    style: { strokeNoScale: true },
                    z2: 100,
                    scale: normalizeSymbolSize(data.getItemVisual(idx, &apos;symbolSize&apos;))
                });
                return symbolPath;
            }
            function updateSymbols(oldPoints, newPoints, symbolGroup, data, idx, isInit) {
                // Simply rerender all
                symbolGroup.removeAll();
                for (var i = 0; i &lt; newPoints.length - 1; i++) {
                    var symbolPath = createSymbol(data, idx);
                    if (symbolPath) {
                        symbolPath.__dimIdx = i;
                        if (oldPoints[i]) {
                            symbolPath.attr(&apos;position&apos;, oldPoints[i]);
                            graphic[isInit ? &apos;initProps&apos; : &apos;updateProps&apos;](symbolPath, { position: newPoints[i] }, seriesModel, idx);
                        } else {
                            symbolPath.attr(&apos;position&apos;, newPoints[i]);
                        }
                        symbolGroup.add(symbolPath);
                    }
                }
            }
            function getInitialPoints(points) {
                return zrUtil.map(points, function (pt) {
                    return [
                        polar.cx,
                        polar.cy
                    ];
                });
            }
            data.diff(oldData).add(function (idx) {
                var points = data.getItemLayout(idx);
                if (!points) {
                    return;
                }
                var polygon = new graphic.Polygon();
                var polyline = new graphic.Polyline();
                var target = { shape: { points: points } };
                polygon.shape.points = getInitialPoints(points);
                polyline.shape.points = getInitialPoints(points);
                graphic.initProps(polygon, target, seriesModel, idx);
                graphic.initProps(polyline, target, seriesModel, idx);
                var itemGroup = new graphic.Group();
                var symbolGroup = new graphic.Group();
                itemGroup.add(polyline);
                itemGroup.add(polygon);
                itemGroup.add(symbolGroup);
                updateSymbols(polyline.shape.points, points, symbolGroup, data, idx, true);
                data.setItemGraphicEl(idx, itemGroup);
            }).update(function (newIdx, oldIdx) {
                var itemGroup = oldData.getItemGraphicEl(oldIdx);
                var polyline = itemGroup.childAt(0);
                var polygon = itemGroup.childAt(1);
                var symbolGroup = itemGroup.childAt(2);
                var target = { shape: { points: data.getItemLayout(newIdx) } };
                if (!target.shape.points) {
                    return;
                }
                updateSymbols(polyline.shape.points, target.shape.points, symbolGroup, data, newIdx, false);
                graphic.updateProps(polyline, target, seriesModel);
                graphic.updateProps(polygon, target, seriesModel);
                data.setItemGraphicEl(newIdx, itemGroup);
            }).remove(function (idx) {
                group.remove(oldData.getItemGraphicEl(idx));
            }).execute();
            data.eachItemGraphicEl(function (itemGroup, idx) {
                var itemModel = data.getItemModel(idx);
                var polyline = itemGroup.childAt(0);
                var polygon = itemGroup.childAt(1);
                var symbolGroup = itemGroup.childAt(2);
                var color = data.getItemVisual(idx, &apos;color&apos;);
                group.add(itemGroup);
                polyline.useStyle(zrUtil.defaults(itemModel.getModel(&apos;lineStyle.normal&apos;).getLineStyle(), {
                    fill: &apos;none&apos;,
                    stroke: color
                }));
                polyline.hoverStyle = itemModel.getModel(&apos;lineStyle.emphasis&apos;).getLineStyle();
                var areaStyleModel = itemModel.getModel(&apos;areaStyle.normal&apos;);
                var hoverAreaStyleModel = itemModel.getModel(&apos;areaStyle.emphasis&apos;);
                var polygonIgnore = areaStyleModel.isEmpty() &amp;&amp; areaStyleModel.parentModel.isEmpty();
                var hoverPolygonIgnore = hoverAreaStyleModel.isEmpty() &amp;&amp; hoverAreaStyleModel.parentModel.isEmpty();
                hoverPolygonIgnore = hoverPolygonIgnore &amp;&amp; polygonIgnore;
                polygon.ignore = polygonIgnore;
                polygon.useStyle(zrUtil.defaults(areaStyleModel.getAreaStyle(), {
                    fill: color,
                    opacity: 0.7
                }));
                polygon.hoverStyle = hoverAreaStyleModel.getAreaStyle();
                var itemStyle = itemModel.getModel(&apos;itemStyle.normal&apos;).getItemStyle([&apos;color&apos;]);
                var itemHoverStyle = itemModel.getModel(&apos;itemStyle.emphasis&apos;).getItemStyle();
                var labelModel = itemModel.getModel(&apos;label.normal&apos;);
                var labelHoverModel = itemModel.getModel(&apos;label.emphasis&apos;);
                symbolGroup.eachChild(function (symbolPath) {
                    symbolPath.setStyle(itemStyle);
                    symbolPath.hoverStyle = zrUtil.clone(itemHoverStyle);
                    var defaultText = data.get(data.dimensions[symbolPath.__dimIdx], idx);
                    graphic.setText(symbolPath.style, labelModel, color);
                    symbolPath.setStyle({ text: labelModel.get(&apos;show&apos;) ? zrUtil.retrieve(seriesModel.getFormattedLabel(idx, &apos;normal&apos;, null, symbolPath.__dimIdx), defaultText) : &apos;&apos; });
                    graphic.setText(symbolPath.hoverStyle, labelHoverModel, color);
                    symbolPath.hoverStyle.text = labelHoverModel.get(&apos;show&apos;) ? zrUtil.retrieve(seriesModel.getFormattedLabel(idx, &apos;emphasis&apos;, null, symbolPath.__dimIdx), defaultText) : &apos;&apos;;
                });
                function onEmphasis() {
                    polygon.attr(&apos;ignore&apos;, hoverPolygonIgnore);
                }
                function onNormal() {
                    polygon.attr(&apos;ignore&apos;, polygonIgnore);
                }
                itemGroup.off(&apos;mouseover&apos;).off(&apos;mouseout&apos;).off(&apos;normal&apos;).off(&apos;emphasis&apos;);
                itemGroup.on(&apos;emphasis&apos;, onEmphasis).on(&apos;mouseover&apos;, onEmphasis).on(&apos;normal&apos;, onNormal).on(&apos;mouseout&apos;, onNormal);
                graphic.setHoverStyle(itemGroup);
            });
            this._data = data;
        },
        remove: function () {
            this.group.removeAll();
            this._data = null;
        }
    });
});
define(&apos;echarts/chart/radar/radarLayout&apos;, [&apos;require&apos;], function (require) {
    return function (ecModel) {
        ecModel.eachSeriesByType(&apos;radar&apos;, function (seriesModel) {
            var data = seriesModel.getData();
            var points = [];
            var coordSys = seriesModel.coordinateSystem;
            if (!coordSys) {
                return;
            }
            function pointsConverter(val, idx) {
                points[idx] = points[idx] || [];
                points[idx][i] = coordSys.dataToPoint(val, i);
            }
            for (var i = 0; i &lt; coordSys.getIndicatorAxes().length; i++) {
                var dim = data.dimensions[i];
                data.each(dim, pointsConverter);
            }
            data.each(function (idx) {
                // Close polygon
                points[idx][0] &amp;&amp; points[idx].push(points[idx][0].slice());
                data.setItemLayout(idx, points[idx]);
            });
        });
    };
});
define(&apos;echarts/chart/radar/backwardCompat&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    return function (option) {
        var polarOptArr = option.polar;
        if (polarOptArr) {
            if (!zrUtil.isArray(polarOptArr)) {
                polarOptArr = [polarOptArr];
            }
            var polarNotRadar = [];
            zrUtil.each(polarOptArr, function (polarOpt, idx) {
                if (polarOpt.indicator) {
                    if (polarOpt.type &amp;&amp; !polarOpt.shape) {
                        polarOpt.shape = polarOpt.type;
                    }
                    option.radar = option.radar || [];
                    if (!zrUtil.isArray(option.radar)) {
                        option.radar = [option.radar];
                    }
                    option.radar.push(polarOpt);
                } else {
                    polarNotRadar.push(polarOpt);
                }
            });
            option.polar = polarNotRadar;
        }
        zrUtil.each(option.series, function (seriesOpt) {
            if (seriesOpt.type === &apos;radar&apos; &amp;&amp; seriesOpt.polarIndex) {
                seriesOpt.radarIndex = seriesOpt.polarIndex;
            }
        });
    };
});
define(&apos;zrender/core/env&apos;, [], function () {
    var env = {};
    if (typeof navigator === &apos;undefined&apos;) {
        // In node
        env = {
            browser: {},
            os: {},
            node: true,
            canvasSupported: true
        };
    } else {
        env = detect(navigator.userAgent);
    }
    return env;
    // Zepto.js
    // (c) 2010-2013 Thomas Fuchs
    // Zepto.js may be freely distributed under the MIT license.
    function detect(ua) {
        var os = {};
        var browser = {};
        // var webkit = ua.match(/Web[kK]it[\/]{0,1}([\d.]+)/);
        // var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
        // var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
        // var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
        // var iphone = !ipad &amp;&amp; ua.match(/(iPhone\sOS)\s([\d_]+)/);
        // var webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/);
        // var touchpad = webos &amp;&amp; ua.match(/TouchPad/);
        // var kindle = ua.match(/Kindle\/([\d.]+)/);
        // var silk = ua.match(/Silk\/([\d._]+)/);
        // var blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/);
        // var bb10 = ua.match(/(BB10).*Version\/([\d.]+)/);
        // var rimtabletos = ua.match(/(RIM\sTablet\sOS)\s([\d.]+)/);
        // var playbook = ua.match(/PlayBook/);
        // var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);
        var firefox = ua.match(/Firefox\/([\d.]+)/);
        // var safari = webkit &amp;&amp; ua.match(/Mobile\//) &amp;&amp; !chrome;
        // var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) &amp;&amp; !chrome;
        var ie = ua.match(/MSIE\s([\d.]+)/) || ua.match(/Trident\/.+?rv:(([\d.]+))/);
        var edge = ua.match(/Edge\/([\d.]+)/);
        // IE 12 and 12+
        // Todo: clean this up with a better OS/browser seperation:
        // - discern (more) between multiple browsers on android
        // - decide if kindle fire in silk mode is android or not
        // - Firefox on Android doesn&apos;t specify the Android version
        // - possibly devide in os, device and browser hashes
        // if (browser.webkit = !!webkit) browser.version = webkit[1];
        // if (android) os.android = true, os.version = android[2];
        // if (iphone &amp;&amp; !ipod) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, &apos;.&apos;);
        // if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, &apos;.&apos;);
        // if (ipod) os.ios = os.ipod = true, os.version = ipod[3] ? ipod[3].replace(/_/g, &apos;.&apos;) : null;
        // if (webos) os.webos = true, os.version = webos[2];
        // if (touchpad) os.touchpad = true;
        // if (blackberry) os.blackberry = true, os.version = blackberry[2];
        // if (bb10) os.bb10 = true, os.version = bb10[2];
        // if (rimtabletos) os.rimtabletos = true, os.version = rimtabletos[2];
        // if (playbook) browser.playbook = true;
        // if (kindle) os.kindle = true, os.version = kindle[1];
        // if (silk) browser.silk = true, browser.version = silk[1];
        // if (!silk &amp;&amp; os.android &amp;&amp; ua.match(/Kindle Fire/)) browser.silk = true;
        // if (chrome) browser.chrome = true, browser.version = chrome[1];
        if (firefox)
            browser.firefox = true, browser.version = firefox[1];
        // if (safari &amp;&amp; (ua.match(/Safari/) || !!os.ios)) browser.safari = true;
        // if (webview) browser.webview = true;
        if (ie) {
            browser.ie = true;
            browser.version = ie[1];
        }
        if (ie) {
            browser.ie = true;
            browser.version = ie[1];
        }
        if (edge) {
            browser.edge = true;
            browser.version = edge[1];
        }
        // os.tablet = !!(ipad || playbook || (android &amp;&amp; !ua.match(/Mobile/)) ||
        //     (firefox &amp;&amp; ua.match(/Tablet/)) || (ie &amp;&amp; !ua.match(/Phone/) &amp;&amp; ua.match(/Touch/)));
        // os.phone  = !!(!os.tablet &amp;&amp; !os.ipod &amp;&amp; (android || iphone || webos ||
        //     (chrome &amp;&amp; ua.match(/Android/)) || (chrome &amp;&amp; ua.match(/CriOS\/([\d.]+)/)) ||
        //     (firefox &amp;&amp; ua.match(/Mobile/)) || (ie &amp;&amp; ua.match(/Touch/))));
        return {
            browser: browser,
            os: os,
            node: false,
            canvasSupported: document.createElement(&apos;canvas&apos;).getContext ? true : false,
            touchEventsSupported: &apos;ontouchstart&apos; in window &amp;&amp; !browser.ie &amp;&amp; !browser.edge,
            pointerEventsSupported: &apos;onpointerdown&apos; in window &amp;&amp; (browser.edge || browser.ie &amp;&amp; browser.version &gt;= 10)
        };
    }
});
define(&apos;echarts/ExtensionAPI&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;], function (require) {
    &apos;use strict&apos;;
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var echartsAPIList = [
            &apos;getDom&apos;,
            &apos;getZr&apos;,
            &apos;getWidth&apos;,
            &apos;getHeight&apos;,
            &apos;dispatchAction&apos;,
            &apos;isDisposed&apos;,
            &apos;on&apos;,
            &apos;off&apos;,
            &apos;getDataURL&apos;,
            &apos;getConnectedDataURL&apos;,
            &apos;getModel&apos;,
            &apos;getOption&apos;
        ];
    function ExtensionAPI(chartInstance) {
        zrUtil.each(echartsAPIList, function (name) {
            this[name] = zrUtil.bind(chartInstance[name], chartInstance);
        }, this);
    }
    return ExtensionAPI;
});
define(&apos;echarts/component/radar&apos;, [&apos;require&apos;, &apos;../coord/radar/Radar&apos;, &apos;../coord/radar/RadarModel&apos;, &apos;./radar/RadarView&apos;], function (require) {
    require(&apos;../coord/radar/Radar&apos;);
    require(&apos;../coord/radar/RadarModel&apos;);
    require(&apos;./radar/RadarView&apos;);
});
define(&apos;echarts/model/Global&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../util/model&apos;, &apos;./Model&apos;, &apos;./Component&apos;, &apos;./globalDefault&apos;, &apos;./mixin/colorPalette&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var modelUtil = require(&apos;../util/model&apos;);
    var Model = require(&apos;./Model&apos;);
    var each = zrUtil.each;
    var filter = zrUtil.filter;
    var map = zrUtil.map;
    var isArray = zrUtil.isArray;
    var indexOf = zrUtil.indexOf;
    var isObject = zrUtil.isObject;
    var ComponentModel = require(&apos;./Component&apos;);
    var globalDefault = require(&apos;./globalDefault&apos;);
    var OPTION_INNER_KEY = &apos; _ec_inner&apos;;
    /**
     * @alias module:echarts/model/Global
     *
     * @param {Object} option
     * @param {module:echarts/model/Model} parentModel
     * @param {Object} theme
     */
    var GlobalModel = Model.extend({
            constructor: GlobalModel,
            init: function (option, parentModel, theme, optionManager) {
                theme = theme || {};
                this.option = null;
                // Mark as not initialized.
                /**
             * @type {module:echarts/model/Model}
             * @private
             */
                this._theme = new Model(theme);
                /**
             * @type {module:echarts/model/OptionManager}
             */
                this._optionManager = optionManager;
            },
            setOption: function (option, optionPreprocessorFuncs) {
                zrUtil.assert(!(OPTION_INNER_KEY in option), &apos;please use chart.getOption()&apos;);
                this._optionManager.setOption(option, optionPreprocessorFuncs);
                this.resetOption();
            },
            resetOption: function (type) {
                var optionChanged = false;
                var optionManager = this._optionManager;
                if (!type || type === &apos;recreate&apos;) {
                    var baseOption = optionManager.mountOption(type === &apos;recreate&apos;);
                    if (!this.option || type === &apos;recreate&apos;) {
                        initBase.call(this, baseOption);
                    } else {
                        this.restoreData();
                        this.mergeOption(baseOption);
                    }
                    optionChanged = true;
                }
                if (type === &apos;timeline&apos; || type === &apos;media&apos;) {
                    this.restoreData();
                }
                if (!type || type === &apos;recreate&apos; || type === &apos;timeline&apos;) {
                    var timelineOption = optionManager.getTimelineOption(this);
                    timelineOption &amp;&amp; (this.mergeOption(timelineOption), optionChanged = true);
                }
                if (!type || type === &apos;recreate&apos; || type === &apos;media&apos;) {
                    var mediaOptions = optionManager.getMediaOption(this, this._api);
                    if (mediaOptions.length) {
                        each(mediaOptions, function (mediaOption) {
                            this.mergeOption(mediaOption, optionChanged = true);
                        }, this);
                    }
                }
                return optionChanged;
            },
            mergeOption: function (newOption) {
                var option = this.option;
                var componentsMap = this._componentsMap;
                var newCptTypes = [];
                // &#x5982;&#x679C;&#x4E0D;&#x5B58;&#x5728;&#x5BF9;&#x5E94;&#x7684; component model &#x5219;&#x76F4;&#x63A5; merge
                each(newOption, function (componentOption, mainType) {
                    if (componentOption == null) {
                        return;
                    }
                    if (!ComponentModel.hasClass(mainType)) {
                        option[mainType] = option[mainType] == null ? zrUtil.clone(componentOption) : zrUtil.merge(option[mainType], componentOption, true);
                    } else {
                        newCptTypes.push(mainType);
                    }
                });
                // FIXME OPTION &#x540C;&#x6B65;&#x662F;&#x5426;&#x8981;&#x6539;&#x56DE;&#x539F;&#x6765;&#x7684;
                ComponentModel.topologicalTravel(newCptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this);
                function visitComponent(mainType, dependencies) {
                    var newCptOptionList = modelUtil.normalizeToArray(newOption[mainType]);
                    var mapResult = modelUtil.mappingToExists(componentsMap[mainType], newCptOptionList);
                    makeKeyInfo(mainType, mapResult);
                    var dependentModels = getComponentsByTypes(componentsMap, dependencies);
                    option[mainType] = [];
                    componentsMap[mainType] = [];
                    each(mapResult, function (resultItem, index) {
                        var componentModel = resultItem.exist;
                        var newCptOption = resultItem.option;
                        zrUtil.assert(isObject(newCptOption) || componentModel, &apos;Empty component definition&apos;);
                        // Consider where is no new option and should be merged using {},
                        // see removeEdgeAndAdd in topologicalTravel and
                        // ComponentModel.getAllClassMainTypes.
                        if (!newCptOption) {
                            componentModel.mergeOption({}, this);
                            componentModel.optionUpdated({}, false);
                        } else {
                            var ComponentModelClass = ComponentModel.getClass(mainType, resultItem.keyInfo.subType, true);
                            if (componentModel &amp;&amp; componentModel instanceof ComponentModelClass) {
                                componentModel.mergeOption(newCptOption, this);
                                componentModel.optionUpdated(newCptOption, false);
                            } else {
                                // PENDING Global as parent ?
                                var extraOpt = zrUtil.extend({
                                        dependentModels: dependentModels,
                                        componentIndex: index
                                    }, resultItem.keyInfo);
                                componentModel = new ComponentModelClass(newCptOption, this, this, extraOpt);
                                componentModel.init(newCptOption, this, this, extraOpt);
                                // Call optionUpdated after init.
                                // newCptOption has been used as componentModel.option
                                // and may be merged with theme and default, so pass null
                                // to avoid confusion.
                                componentModel.optionUpdated(null, true);
                            }
                        }
                        componentsMap[mainType][index] = componentModel;
                        option[mainType][index] = componentModel.option;
                    }, this);
                    // Backup series for filtering.
                    if (mainType === &apos;series&apos;) {
                        this._seriesIndices = createSeriesIndices(componentsMap.series);
                    }
                }
            },
            getOption: function () {
                var option = zrUtil.clone(this.option);
                each(option, function (opts, mainType) {
                    if (ComponentModel.hasClass(mainType)) {
                        var opts = modelUtil.normalizeToArray(opts);
                        for (var i = opts.length - 1; i &gt;= 0; i--) {
                            // Remove options with inner id.
                            if (modelUtil.isIdInner(opts[i])) {
                                opts.splice(i, 1);
                            }
                        }
                        option[mainType] = opts;
                    }
                });
                delete option[OPTION_INNER_KEY];
                return option;
            },
            getTheme: function () {
                return this._theme;
            },
            getComponent: function (mainType, idx) {
                var list = this._componentsMap[mainType];
                if (list) {
                    return list[idx || 0];
                }
            },
            queryComponents: function (condition) {
                var mainType = condition.mainType;
                if (!mainType) {
                    return [];
                }
                var index = condition.index;
                var id = condition.id;
                var name = condition.name;
                var cpts = this._componentsMap[mainType];
                if (!cpts || !cpts.length) {
                    return [];
                }
                var result;
                if (index != null) {
                    if (!isArray(index)) {
                        index = [index];
                    }
                    result = filter(map(index, function (idx) {
                        return cpts[idx];
                    }), function (val) {
                        return !!val;
                    });
                } else if (id != null) {
                    var isIdArray = isArray(id);
                    result = filter(cpts, function (cpt) {
                        return isIdArray &amp;&amp; indexOf(id, cpt.id) &gt;= 0 || !isIdArray &amp;&amp; cpt.id === id;
                    });
                } else if (name != null) {
                    var isNameArray = isArray(name);
                    result = filter(cpts, function (cpt) {
                        return isNameArray &amp;&amp; indexOf(name, cpt.name) &gt;= 0 || !isNameArray &amp;&amp; cpt.name === name;
                    });
                }
                return filterBySubType(result, condition);
            },
            findComponents: function (condition) {
                var query = condition.query;
                var mainType = condition.mainType;
                var queryCond = getQueryCond(query);
                var result = queryCond ? this.queryComponents(queryCond) : this._componentsMap[mainType];
                return doFilter(filterBySubType(result, condition));
                function getQueryCond(q) {
                    var indexAttr = mainType + &apos;Index&apos;;
                    var idAttr = mainType + &apos;Id&apos;;
                    var nameAttr = mainType + &apos;Name&apos;;
                    return q &amp;&amp; (q.hasOwnProperty(indexAttr) || q.hasOwnProperty(idAttr) || q.hasOwnProperty(nameAttr)) ? {
                        mainType: mainType,
                        index: q[indexAttr],
                        id: q[idAttr],
                        name: q[nameAttr]
                    } : null;
                }
                function doFilter(res) {
                    return condition.filter ? filter(res, condition.filter) : res;
                }
            },
            eachComponent: function (mainType, cb, context) {
                var componentsMap = this._componentsMap;
                if (typeof mainType === &apos;function&apos;) {
                    context = cb;
                    cb = mainType;
                    each(componentsMap, function (components, componentType) {
                        each(components, function (component, index) {
                            cb.call(context, componentType, component, index);
                        });
                    });
                } else if (zrUtil.isString(mainType)) {
                    each(componentsMap[mainType], cb, context);
                } else if (isObject(mainType)) {
                    var queryResult = this.findComponents(mainType);
                    each(queryResult, cb, context);
                }
            },
            getSeriesByName: function (name) {
                var series = this._componentsMap.series;
                return filter(series, function (oneSeries) {
                    return oneSeries.name === name;
                });
            },
            getSeriesByIndex: function (seriesIndex) {
                return this._componentsMap.series[seriesIndex];
            },
            getSeriesByType: function (subType) {
                var series = this._componentsMap.series;
                return filter(series, function (oneSeries) {
                    return oneSeries.subType === subType;
                });
            },
            getSeries: function () {
                return this._componentsMap.series.slice();
            },
            eachSeries: function (cb, context) {
                assertSeriesInitialized(this);
                each(this._seriesIndices, function (rawSeriesIndex) {
                    var series = this._componentsMap.series[rawSeriesIndex];
                    cb.call(context, series, rawSeriesIndex);
                }, this);
            },
            eachRawSeries: function (cb, context) {
                each(this._componentsMap.series, cb, context);
            },
            eachSeriesByType: function (subType, cb, context) {
                assertSeriesInitialized(this);
                each(this._seriesIndices, function (rawSeriesIndex) {
                    var series = this._componentsMap.series[rawSeriesIndex];
                    if (series.subType === subType) {
                        cb.call(context, series, rawSeriesIndex);
                    }
                }, this);
            },
            eachRawSeriesByType: function (subType, cb, context) {
                return each(this.getSeriesByType(subType), cb, context);
            },
            isSeriesFiltered: function (seriesModel) {
                assertSeriesInitialized(this);
                return zrUtil.indexOf(this._seriesIndices, seriesModel.componentIndex) &lt; 0;
            },
            filterSeries: function (cb, context) {
                assertSeriesInitialized(this);
                var filteredSeries = filter(this._componentsMap.series, cb, context);
                this._seriesIndices = createSeriesIndices(filteredSeries);
            },
            restoreData: function () {
                var componentsMap = this._componentsMap;
                this._seriesIndices = createSeriesIndices(componentsMap.series);
                var componentTypes = [];
                each(componentsMap, function (components, componentType) {
                    componentTypes.push(componentType);
                });
                ComponentModel.topologicalTravel(componentTypes, ComponentModel.getAllClassMainTypes(), function (componentType, dependencies) {
                    each(componentsMap[componentType], function (component) {
                        component.restoreData();
                    });
                });
            }
        });
    /**
     * @inner
     */
    function mergeTheme(option, theme) {
        for (var name in theme) {
            // &#x5982;&#x679C;&#x6709; component model &#x5219;&#x628A;&#x5177;&#x4F53;&#x7684; merge &#x903B;&#x8F91;&#x4EA4;&#x7ED9;&#x8BE5; model &#x5904;&#x7406;
            if (!ComponentModel.hasClass(name)) {
                if (typeof theme[name] === &apos;object&apos;) {
                    option[name] = !option[name] ? zrUtil.clone(theme[name]) : zrUtil.merge(option[name], theme[name], false);
                } else {
                    if (option[name] == null) {
                        option[name] = theme[name];
                    }
                }
            }
        }
    }
    function initBase(baseOption) {
        baseOption = baseOption;
        // Using OPTION_INNER_KEY to mark that this option can not be used outside,
        // i.e. `chart.setOption(chart.getModel().option);` is forbiden.
        this.option = {};
        this.option[OPTION_INNER_KEY] = 1;
        /**
         * @type {Object.<string, array.<module:echarts="" model="">&gt;}
         * @private
         */
        this._componentsMap = {};
        /**
         * Mapping between filtered series list and raw series list.
         * key: filtered series indices, value: raw series indices.
         * @type {Array.<nubmer>}
         * @private
         */
        this._seriesIndices = null;
        mergeTheme(baseOption, this._theme.option);
        // TODO Needs clone when merging to the unexisted property
        zrUtil.merge(baseOption, globalDefault, false);
        this.mergeOption(baseOption);
    }
    /**
     * @inner
     * @param {Array.<string>|string} types model types
     * @return {Object} key: {string} type, value: {Array.<object>} models
     */
    function getComponentsByTypes(componentsMap, types) {
        if (!zrUtil.isArray(types)) {
            types = types ? [types] : [];
        }
        var ret = {};
        each(types, function (type) {
            ret[type] = (componentsMap[type] || []).slice();
        });
        return ret;
    }
    /**
     * @inner
     */
    function makeKeyInfo(mainType, mapResult) {
        // We use this id to hash component models and view instances
        // in echarts. id can be specified by user, or auto generated.
        // The id generation rule ensures new view instance are able
        // to mapped to old instance when setOption are called in
        // no-merge mode. So we generate model id by name and plus
        // type in view id.
        // name can be duplicated among components, which is convenient
        // to specify multi components (like series) by one name.
        // Ensure that each id is distinct.
        var idMap = {};
        each(mapResult, function (item, index) {
            var existCpt = item.exist;
            existCpt &amp;&amp; (idMap[existCpt.id] = item);
        });
        each(mapResult, function (item, index) {
            var opt = item.option;
            zrUtil.assert(!opt || opt.id == null || !idMap[opt.id] || idMap[opt.id] === item, &apos;id duplicates: &apos; + (opt &amp;&amp; opt.id));
            opt &amp;&amp; opt.id != null &amp;&amp; (idMap[opt.id] = item);
            // Complete subType
            if (isObject(opt)) {
                var subType = determineSubType(mainType, opt, item.exist);
                item.keyInfo = {
                    mainType: mainType,
                    subType: subType
                };
            }
        });
        // Make name and id.
        each(mapResult, function (item, index) {
            var existCpt = item.exist;
            var opt = item.option;
            var keyInfo = item.keyInfo;
            if (!isObject(opt)) {
                return;
            }
            // name can be overwitten. Consider case: axis.name = &apos;20km&apos;.
            // But id generated by name will not be changed, which affect
            // only in that case: setOption with &apos;not merge mode&apos; and view
            // instance will be recreated, which can be accepted.
            keyInfo.name = opt.name != null ? opt.name + &apos;&apos; : existCpt ? existCpt.name : &apos; -&apos;;
            if (existCpt) {
                keyInfo.id = existCpt.id;
            } else if (opt.id != null) {
                keyInfo.id = opt.id + &apos;&apos;;
            } else {
                // Consider this situatoin:
                //  optionA: [{name: &apos;a&apos;}, {name: &apos;a&apos;}, {..}]
                //  optionB [{..}, {name: &apos;a&apos;}, {name: &apos;a&apos;}]
                // Series with the same name between optionA and optionB
                // should be mapped.
                var idNum = 0;
                do {
                    keyInfo.id = &apos; &apos; + keyInfo.name + &apos; &apos; + idNum++;
                } while (idMap[keyInfo.id]);
            }
            idMap[keyInfo.id] = item;
        });
    }
    /**
     * @inner
     */
    function determineSubType(mainType, newCptOption, existComponent) {
        var subType = newCptOption.type ? newCptOption.type : existComponent ? existComponent.subType : ComponentModel.determineSubType(mainType, newCptOption);
        // tooltip, markline, markpoint may always has no subType
        return subType;
    }
    /**
     * @inner
     */
    function createSeriesIndices(seriesModels) {
        return map(seriesModels, function (series) {
            return series.componentIndex;
        }) || [];
    }
    /**
     * @inner
     */
    function filterBySubType(components, condition) {
        // Using hasOwnProperty for restrict. Consider
        // subType is undefined in user payload.
        return condition.hasOwnProperty(&apos;subType&apos;) ? filter(components, function (cpt) {
            return cpt.subType === condition.subType;
        }) : components;
    }
    /**
     * @inner
     */
    function assertSeriesInitialized(ecModel) {
        // Components that use _seriesIndices should depends on series component,
        // which make sure that their initialization is after series.
        if (true) {
            if (!ecModel._seriesIndices) {
                throw new Error(&apos;Series has not been initialized yet.&apos;);
            }
        }
    }
    zrUtil.mixin(GlobalModel, require(&apos;./mixin/colorPalette&apos;));
    return GlobalModel;
});
define(&apos;echarts/action/createDataSelectAction&apos;, [&apos;require&apos;, &apos;../echarts&apos;, &apos;zrender/core/util&apos;], function (require) {
    var echarts = require(&apos;../echarts&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    return function (seriesType, actionInfos) {
        zrUtil.each(actionInfos, function (actionInfo) {
            actionInfo.update = &apos;updateView&apos;;
            /**
             * @payload
             * @property {string} seriesName
             * @property {string} name
             */
            echarts.registerAction(actionInfo, function (payload, ecModel) {
                var selected = {};
                ecModel.eachComponent({
                    mainType: &apos;series&apos;,
                    subType: seriesType,
                    query: payload
                }, function (seriesModel) {
                    if (seriesModel[actionInfo.method]) {
                        seriesModel[actionInfo.method](payload.name);
                    }
                    var data = seriesModel.getData();
                    // Create selected map
                    data.each(function (idx) {
                        var name = data.getName(idx);
                        selected[name] = seriesModel.isSelected(name) || false;
                    });
                });
                return {
                    name: payload.name,
                    selected: selected
                };
            });
        });
    };
});
define(&apos;echarts/CoordinateSystem&apos;, [&apos;require&apos;], function (require) {
    &apos;use strict&apos;;
    var coordinateSystemCreators = {};
    function CoordinateSystemManager() {
        this._coordinateSystems = [];
    }
    CoordinateSystemManager.prototype = {
        constructor: CoordinateSystemManager,
        create: function (ecModel, api) {
            var coordinateSystems = [];
            for (var type in coordinateSystemCreators) {
                var list = coordinateSystemCreators[type].create(ecModel, api);
                list &amp;&amp; (coordinateSystems = coordinateSystems.concat(list));
            }
            this._coordinateSystems = coordinateSystems;
        },
        update: function (ecModel, api) {
            var coordinateSystems = this._coordinateSystems;
            for (var i = 0; i &lt; coordinateSystems.length; i++) {
                // FIXME MUST have
                coordinateSystems[i].update &amp;&amp; coordinateSystems[i].update(ecModel, api);
            }
        }
    };
    CoordinateSystemManager.register = function (type, coordinateSystemCreator) {
        coordinateSystemCreators[type] = coordinateSystemCreator;
    };
    CoordinateSystemManager.get = function (type) {
        return coordinateSystemCreators[type];
    };
    return CoordinateSystemManager;
});
define(&apos;echarts/model/OptionManager&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../util/model&apos;, &apos;./Component&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var modelUtil = require(&apos;../util/model&apos;);
    var ComponentModel = require(&apos;./Component&apos;);
    var each = zrUtil.each;
    var clone = zrUtil.clone;
    var map = zrUtil.map;
    var merge = zrUtil.merge;
    var QUERY_REG = /^(min|max)?(.+)$/;
    /**
     * TERM EXPLANATIONS:
     *
     * [option]:
     *
     *     An object that contains definitions of components. For example:
     *     var option = {
     *         title: {...},
     *         legend: {...},
     *         visualMap: {...},
     *         series: [
     *             {data: [...]},
     *             {data: [...]},
     *             ...
     *         ]
     *     };
     *
     * [rawOption]:
     *
     *     An object input to echarts.setOption. &apos;rawOption&apos; may be an
     *     &apos;option&apos;, or may be an object contains multi-options. For example:
     *     var option = {
     *         baseOption: {
     *             title: {...},
     *             legend: {...},
     *             series: [
     *                 {data: [...]},
     *                 {data: [...]},
     *                 ...
     *             ]
     *         },
     *         timeline: {...},
     *         options: [
     *             {title: {...}, series: {data: [...]}},
     *             {title: {...}, series: {data: [...]}},
     *             ...
     *         ],
     *         media: [
     *             {
     *                 query: {maxWidth: 320},
     *                 option: {series: {x: 20}, visualMap: {show: false}}
     *             },
     *             {
     *                 query: {minWidth: 320, maxWidth: 720},
     *                 option: {series: {x: 500}, visualMap: {show: true}}
     *             },
     *             {
     *                 option: {series: {x: 1200}, visualMap: {show: true}}
     *             }
     *         ]
     *     };
     *
     * @alias module:echarts/model/OptionManager
     * @param {module:echarts/ExtensionAPI} api
     */
    function OptionManager(api) {
        /**
         * @private
         * @type {module:echarts/ExtensionAPI}
         */
        this._api = api;
        /**
         * @private
         * @type {Array.<number>}
         */
        this._timelineOptions = [];
        /**
         * @private
         * @type {Array.<object>}
         */
        this._mediaList = [];
        /**
         * @private
         * @type {Object}
         */
        this._mediaDefault;
        /**
         * -1, means default.
         * empty means no media.
         * @private
         * @type {Array.<number>}
         */
        this._currentMediaIndices = [];
        /**
         * @private
         * @type {Object}
         */
        this._optionBackup;
        /**
         * @private
         * @type {Object}
         */
        this._newBaseOption;
    }
    // timeline.notMerge is not supported in ec3. Firstly there is rearly
    // case that notMerge is needed. Secondly supporting &apos;notMerge&apos; requires
    // rawOption cloned and backuped when timeline changed, which does no
    // good to performance. What&apos;s more, that both timeline and setOption
    // method supply &apos;notMerge&apos; brings complex and some problems.
    // Consider this case:
    // (step1) chart.setOption({timeline: {notMerge: false}, ...}, false);
    // (step2) chart.setOption({timeline: {notMerge: true}, ...}, false);
    OptionManager.prototype = {
        constructor: OptionManager,
        setOption: function (rawOption, optionPreprocessorFuncs) {
            rawOption = clone(rawOption, true);
            // FIXME
            // &#x5982;&#x679C; timeline options &#x6216;&#x8005; media &#x4E2D;&#x8BBE;&#x7F6E;&#x4E86;&#x67D0;&#x4E2A;&#x5C5E;&#x6027;&#xFF0C;&#x800C;baseOption&#x4E2D;&#x6CA1;&#x6709;&#x8BBE;&#x7F6E;&#xFF0C;&#x5219;&#x8FDB;&#x884C;&#x8B66;&#x544A;&#x3002;
            var oldOptionBackup = this._optionBackup;
            var newParsedOption = parseRawOption.call(this, rawOption, optionPreprocessorFuncs, !oldOptionBackup);
            this._newBaseOption = newParsedOption.baseOption;
            // For setOption at second time (using merge mode);
            if (oldOptionBackup) {
                // Only baseOption can be merged.
                mergeOption(oldOptionBackup.baseOption, newParsedOption.baseOption);
                // For simplicity, timeline options and media options do not support merge,
                // that is, if you `setOption` twice and both has timeline options, the latter
                // timeline opitons will not be merged to the formers, but just substitude them.
                if (newParsedOption.timelineOptions.length) {
                    oldOptionBackup.timelineOptions = newParsedOption.timelineOptions;
                }
                if (newParsedOption.mediaList.length) {
                    oldOptionBackup.mediaList = newParsedOption.mediaList;
                }
                if (newParsedOption.mediaDefault) {
                    oldOptionBackup.mediaDefault = newParsedOption.mediaDefault;
                }
            } else {
                this._optionBackup = newParsedOption;
            }
        },
        mountOption: function (isRecreate) {
            var optionBackup = this._optionBackup;
            // TODO
            // &#x5982;&#x679C;&#x6CA1;&#x6709;reset&#x529F;&#x80FD;&#x5219;&#x4E0D;clone&#x3002;
            this._timelineOptions = map(optionBackup.timelineOptions, clone);
            this._mediaList = map(optionBackup.mediaList, clone);
            this._mediaDefault = clone(optionBackup.mediaDefault);
            this._currentMediaIndices = [];
            return clone(isRecreate ? optionBackup.baseOption : this._newBaseOption);
        },
        getTimelineOption: function (ecModel) {
            var option;
            var timelineOptions = this._timelineOptions;
            if (timelineOptions.length) {
                // getTimelineOption can only be called after ecModel inited,
                // so we can get currentIndex from timelineModel.
                var timelineModel = ecModel.getComponent(&apos;timeline&apos;);
                if (timelineModel) {
                    option = clone(timelineOptions[timelineModel.getCurrentIndex()], true);
                }
            }
            return option;
        },
        getMediaOption: function (ecModel) {
            var ecWidth = this._api.getWidth();
            var ecHeight = this._api.getHeight();
            var mediaList = this._mediaList;
            var mediaDefault = this._mediaDefault;
            var indices = [];
            var result = [];
            // No media defined.
            if (!mediaList.length &amp;&amp; !mediaDefault) {
                return result;
            }
            // Multi media may be applied, the latter defined media has higher priority.
            for (var i = 0, len = mediaList.length; i &lt; len; i++) {
                if (applyMediaQuery(mediaList[i].query, ecWidth, ecHeight)) {
                    indices.push(i);
                }
            }
            // FIXME
            // &#x662F;&#x5426;mediaDefault&#x5E94;&#x8BE5;&#x5F3A;&#x5236;&#x7528;&#x6237;&#x8BBE;&#x7F6E;&#xFF0C;&#x5426;&#x5219;&#x53EF;&#x80FD;&#x4FEE;&#x6539;&#x4E0D;&#x80FD;&#x56DE;&#x5F52;&#x3002;
            if (!indices.length &amp;&amp; mediaDefault) {
                indices = [-1];
            }
            if (indices.length &amp;&amp; !indicesEquals(indices, this._currentMediaIndices)) {
                result = map(indices, function (index) {
                    return clone(index === -1 ? mediaDefault.option : mediaList[index].option);
                });
            }
            // Otherwise return nothing.
            this._currentMediaIndices = indices;
            return result;
        }
    };
    function parseRawOption(rawOption, optionPreprocessorFuncs, isNew) {
        var timelineOptions = [];
        var mediaList = [];
        var mediaDefault;
        var baseOption;
        // Compatible with ec2.
        var timelineOpt = rawOption.timeline;
        if (rawOption.baseOption) {
            baseOption = rawOption.baseOption;
        }
        // For timeline
        if (timelineOpt || rawOption.options) {
            baseOption = baseOption || {};
            timelineOptions = (rawOption.options || []).slice();
        }
        // For media query
        if (rawOption.media) {
            baseOption = baseOption || {};
            var media = rawOption.media;
            each(media, function (singleMedia) {
                if (singleMedia &amp;&amp; singleMedia.option) {
                    if (singleMedia.query) {
                        mediaList.push(singleMedia);
                    } else if (!mediaDefault) {
                        // Use the first media default.
                        mediaDefault = singleMedia;
                    }
                }
            });
        }
        // For normal option
        if (!baseOption) {
            baseOption = rawOption;
        }
        // Set timelineOpt to baseOption in ec3,
        // which is convenient for merge option.
        if (!baseOption.timeline) {
            baseOption.timeline = timelineOpt;
        }
        // Preprocess.
        each([baseOption].concat(timelineOptions).concat(zrUtil.map(mediaList, function (media) {
            return media.option;
        })), function (option) {
            each(optionPreprocessorFuncs, function (preProcess) {
                preProcess(option, isNew);
            });
        });
        return {
            baseOption: baseOption,
            timelineOptions: timelineOptions,
            mediaDefault: mediaDefault,
            mediaList: mediaList
        };
    }
    /**
     * @see <http: www.w3.org="" tr="" css3-mediaqueries="" #media1="">
     * Support: width, height, aspectRatio
     * Can use max or min as prefix.
     */
    function applyMediaQuery(query, ecWidth, ecHeight) {
        var realMap = {
                width: ecWidth,
                height: ecHeight,
                aspectratio: ecWidth / ecHeight
            };
        var applicatable = true;
        zrUtil.each(query, function (value, attr) {
            var matched = attr.match(QUERY_REG);
            if (!matched || !matched[1] || !matched[2]) {
                return;
            }
            var operator = matched[1];
            var realAttr = matched[2].toLowerCase();
            if (!compare(realMap[realAttr], value, operator)) {
                applicatable = false;
            }
        });
        return applicatable;
    }
    function compare(real, expect, operator) {
        if (operator === &apos;min&apos;) {
            return real &gt;= expect;
        } else if (operator === &apos;max&apos;) {
            return real <= expect;="" }="" else="" {="" equals="" return="" real="==" function="" indicesequals(indices1,="" indices2)="" indices="" is="" always="" order="" by="" asc="" and="" has="" only="" finite="" number.="" indices1.join(',')="==" indices2.join(',');="" **="" *="" consider="" case:="" `chart.setoption(opt1);`="" then="" user="" do="" some="" interaction="" like="" datazoom,="" dataview="" changing.="" `chart.setoption(opt2);`="" press="" 'reset="" button'="" in="" toolbox.="" after="" doing="" that="" all="" of="" the="" effects="" should="" be="" reset,="" chart="" same="" as="" result="" invoke="" `chart.setoption(opt1);="" chart.setoption(opt2);`.="" although="" it="" not="" able="" ensure="" chart.setoption(opt2);`="" equivalents="" to="" `chart.setoption(merge(opt1,="" opt2));`="" exactly,="" this="" might="" simple="" way="" implement="" feature.="" memo:="" we've="" considered="" other="" approaches:="" 1.="" each="" model="" handle="" its="" self="" restoration="" but="" uniform="" treatment.="" (too="" complex="" logic="" error-prone)="" 2.="" use="" a="" shadow="" ecmodel.="" (performace="" expensive)="" mergeoption(oldoption,="" newoption)="" newoption="newOption" ||="" {};="" each(newoption,="" (newcptopt,="" maintype)="" if="" (newcptopt="=" null)="" return;="" var="" oldcptopt="oldOption[mainType];" (!componentmodel.hasclass(maintype))="" oldoption[maintype]="merge(oldCptOpt," newcptopt,="" true);="" newcptopt="modelUtil.normalizeToArray(newCptOpt);" mapresult="modelUtil.mappingToExists(oldCptOpt," newcptopt);="" (item)="" item.option="" &&="" item.exist="" ?="" merge(item.exist,="" item.option,="" true)="" :="" item.option;="" });="" optionmanager;="" define('echarts="" component',="" ['require',="" '.="" model',="" 'zrender="" core="" util',="" '..="" util="" clazz',="" layout',="" mixin="" boxlayout'],="" (require)="" zrutil="require(&apos;zrender/core/util&apos;);" arraypush="Array.prototype.push;" componentutil="require(&apos;../util/component&apos;);" clazzutil="require(&apos;../util/clazz&apos;);" layout="require(&apos;../util/layout&apos;);" @alias="" module:echarts="" component="" @constructor="" @param="" {object}="" option="" {module:echarts="" model}="" parentmodel="" ecmodel="" componentmodel="Model.extend({" type:="" 'component',="" id:="" '',="" name:="" maintype:="" subtype:="" componentindex:="" 0,="" defaultoption:="" null,="" ecmodel:="" dependentmodels:="" [],="" uid:="" layoutmode:="" $constructor:="" (option,="" parentmodel,="" ecmodel,="" extraopt)="" model.call(this,="" option,="" extraopt);="" set="" dependentmodels,="" componentindex,="" name,="" id,="" maintype,="" subtype.="" zrutil.extend(this,="" this.uid="componentUtil.getUID(&apos;componentModel&apos;);" },="" init:="" this.mergedefaultandtheme(option,="" ecmodel);="" mergedefaultandtheme:="" ecmodel)="" layoutmode="this.layoutMode;" inputpositionparams="layoutMode" layout.getlayoutparams(option)="" thememodel="ecModel.getTheme();" zrutil.merge(option,="" thememodel.get(this.maintype));="" this.getdefaultoption());="" (layoutmode)="" layout.mergelayoutparam(option,="" inputpositionparams,="" layoutmode);="" mergeoption:="" (option)="" zrutil.merge(this.option,="" layout.mergelayoutparam(this.option,="" optionupdated:="" (newcptoption,="" isinit)="" getdefaultoption:="" ()="" (!this.hasownproperty('__defaultoption'))="" optlist="[];" class="this.constructor;" while="" (class)="" opt="Class.prototype.defaultOption;" optlist.push(opt);="" defaultoption="{};" for="" (var="" i="optList.length" -="" 1;="">= 0; i--) {
                        defaultOption = zrUtil.merge(defaultOption, optList[i], true);
                    }
                    this.__defaultOption = defaultOption;
                }
                return this.__defaultOption;
            }
        });
    // Reset ComponentModel.extend, add preConstruct.
    // clazzUtil.enableClassExtend(
    //     ComponentModel,
    //     function (option, parentModel, ecModel, extraOpt) {
    //         // Set dependentModels, componentIndex, name, id, mainType, subType.
    //         zrUtil.extend(this, extraOpt);
    //         this.uid = componentUtil.getUID(&apos;componentModel&apos;);
    //         // this.setReadOnly([
    //         //     &apos;type&apos;, &apos;id&apos;, &apos;uid&apos;, &apos;name&apos;, &apos;mainType&apos;, &apos;subType&apos;,
    //         //     &apos;dependentModels&apos;, &apos;componentIndex&apos;
    //         // ]);
    //     }
    // );
    // Add capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.
    clazzUtil.enableClassManagement(ComponentModel, { registerWhenExtend: true });
    componentUtil.enableSubTypeDefaulter(ComponentModel);
    // Add capability of ComponentModel.topologicalTravel.
    componentUtil.enableTopologicalTravel(ComponentModel, getDependencies);
    function getDependencies(componentType) {
        var deps = [];
        zrUtil.each(ComponentModel.getClassesByMainType(componentType), function (Clazz) {
            arrayPush.apply(deps, Clazz.prototype.dependencies || []);
        });
        // Ensure main type
        return zrUtil.map(deps, function (type) {
            return clazzUtil.parseClassType(type).main;
        });
    }
    zrUtil.mixin(ComponentModel, require(&apos;./mixin/boxLayout&apos;));
    return ComponentModel;
});
define(&apos;echarts/model/Series&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../util/format&apos;, &apos;../util/model&apos;, &apos;./Component&apos;, &apos;./mixin/colorPalette&apos;, &apos;zrender/core/env&apos;], function (require) {
    &apos;use strict&apos;;
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var formatUtil = require(&apos;../util/format&apos;);
    var modelUtil = require(&apos;../util/model&apos;);
    var ComponentModel = require(&apos;./Component&apos;);
    var colorPaletteMixin = require(&apos;./mixin/colorPalette&apos;);
    var env = require(&apos;zrender/core/env&apos;);
    var encodeHTML = formatUtil.encodeHTML;
    var addCommas = formatUtil.addCommas;
    var SeriesModel = ComponentModel.extend({
            type: &apos;series.__base__&apos;,
            seriesIndex: 0,
            coordinateSystem: null,
            defaultOption: null,
            legendDataProvider: null,
            visualColorAccessPath: &apos;itemStyle.normal.color&apos;,
            init: function (option, parentModel, ecModel, extraOpt) {
                /**
             * @type {number}
             * @readOnly
             */
                this.seriesIndex = this.componentIndex;
                this.mergeDefaultAndTheme(option, ecModel);
                /**
             * @type {module:echarts/data/List|module:echarts/data/Tree|module:echarts/data/Graph}
             * @private
             */
                this._dataBeforeProcessed = this.getInitialData(option, ecModel);
                // If we reverse the order (make this._data firstly, and then make
                // this._dataBeforeProcessed by cloneShallow), cloneShallow will
                // cause this._data.graph.data !== this._data when using
                // module:echarts/data/Graph or module:echarts/data/Tree.
                // See module:echarts/data/helper/linkList
                this._data = this._dataBeforeProcessed.cloneShallow();
            },
            mergeDefaultAndTheme: function (option, ecModel) {
                zrUtil.merge(option, ecModel.getTheme().get(this.subType));
                zrUtil.merge(option, this.getDefaultOption());
                // Default label emphasis `position` and `show`
                // FIXME Set label in mergeOption
                modelUtil.defaultEmphasis(option.label, modelUtil.LABEL_OPTIONS);
                this.fillDataTextStyle(option.data);
            },
            mergeOption: function (newSeriesOption, ecModel) {
                newSeriesOption = zrUtil.merge(this.option, newSeriesOption, true);
                this.fillDataTextStyle(newSeriesOption.data);
                var data = this.getInitialData(newSeriesOption, ecModel);
                // TODO Merge data?
                if (data) {
                    this._data = data;
                    this._dataBeforeProcessed = data.cloneShallow();
                }
            },
            fillDataTextStyle: function (data) {
                // Default data label emphasis `position` and `show`
                // FIXME Tree structure data ?
                // FIXME Performance ?
                if (data) {
                    for (var i = 0; i &lt; data.length; i++) {
                        if (data[i] &amp;&amp; data[i].label) {
                            modelUtil.defaultEmphasis(data[i].label, modelUtil.LABEL_OPTIONS);
                        }
                    }
                }
            },
            getInitialData: function () {
            },
            getData: function (dataType) {
                return dataType == null ? this._data : this._data.getLinkedData(dataType);
            },
            setData: function (data) {
                this._data = data;
            },
            getRawData: function () {
                return this._dataBeforeProcessed;
            },
            coordDimToDataDim: function (coordDim) {
                return [coordDim];
            },
            dataDimToCoordDim: function (dataDim) {
                return dataDim;
            },
            getBaseAxis: function () {
                var coordSys = this.coordinateSystem;
                return coordSys &amp;&amp; coordSys.getBaseAxis &amp;&amp; coordSys.getBaseAxis();
            },
            formatTooltip: function (dataIndex, multipleSeries, dataType) {
                function formatArrayValue(value) {
                    return zrUtil.map(value, function (val, idx) {
                        var dimInfo = data.getDimensionInfo(idx);
                        var dimType = dimInfo &amp;&amp; dimInfo.type;
                        if (dimType === &apos;ordinal&apos;) {
                            return val;
                        } else if (dimType === &apos;time&apos;) {
                            return multipleSeries ? &apos;&apos; : formatUtil.formatTime(&apos;yyyy/mm/dd hh:mm:ss&apos;, val);
                        } else {
                            return addCommas(val);
                        }
                    }).filter(function (val) {
                        return !!val;
                    }).join(&apos;, &apos;);
                }
                var data = this._data;
                var value = this.getRawValue(dataIndex);
                var formattedValue = zrUtil.isArray(value) ? formatArrayValue(value) : addCommas(value);
                var name = data.getName(dataIndex);
                var color = data.getItemVisual(dataIndex, &apos;color&apos;);
                var colorEl = &apos;<span style="display:inline-block;margin-right:5px;&apos; + &apos;border-radius:10px;width:9px;height:9px;background-color:&apos; + color + &apos;"></span>&apos;;
                var seriesName = this.name;
                // FIXME
                if (seriesName === &apos; -&apos;) {
                    // Not show &apos;-&apos;
                    seriesName = &apos;&apos;;
                }
                return !multipleSeries ? (seriesName &amp;&amp; encodeHTML(seriesName) + &apos;<br>&apos;) + colorEl + (name ? encodeHTML(name) + &apos; : &apos; + formattedValue : formattedValue) : colorEl + encodeHTML(this.name) + &apos; : &apos; + formattedValue;
            },
            ifEnableAnimation: function () {
                if (env.node) {
                    return false;
                }
                var animationEnabled = this.getShallow(&apos;animation&apos;);
                if (animationEnabled) {
                    if (this.getData().count() &gt; this.getShallow(&apos;animationThreshold&apos;)) {
                        animationEnabled = false;
                    }
                }
                return animationEnabled;
            },
            restoreData: function () {
                this._data = this._dataBeforeProcessed.cloneShallow();
            },
            getColorFromPalette: function (name, scope) {
                var ecModel = this.ecModel;
                // PENDING
                var color = colorPaletteMixin.getColorFromPalette.call(this, name, scope);
                if (!color) {
                    color = ecModel.getColorFromPalette(name, scope);
                }
                return color;
            },
            getAxisTooltipDataIndex: null
        });
    zrUtil.mixin(SeriesModel, modelUtil.dataFormatMixin);
    zrUtil.mixin(SeriesModel, colorPaletteMixin);
    return SeriesModel;
});
define(&apos;echarts/view/Chart&apos;, [&apos;require&apos;, &apos;zrender/container/Group&apos;, &apos;../util/component&apos;, &apos;../util/clazz&apos;], function (require) {
    var Group = require(&apos;zrender/container/Group&apos;);
    var componentUtil = require(&apos;../util/component&apos;);
    var clazzUtil = require(&apos;../util/clazz&apos;);
    function Chart() {
        /**
         * @type {module:zrender/container/Group}
         * @readOnly
         */
        this.group = new Group();
        /**
         * @type {string}
         * @readOnly
         */
        this.uid = componentUtil.getUID(&apos;viewChart&apos;);
    }
    Chart.prototype = {
        type: &apos;chart&apos;,
        init: function (ecModel, api) {
        },
        render: function (seriesModel, ecModel, api, payload) {
        },
        highlight: function (seriesModel, ecModel, api, payload) {
            toggleHighlight(seriesModel.getData(), payload, &apos;emphasis&apos;);
        },
        downplay: function (seriesModel, ecModel, api, payload) {
            toggleHighlight(seriesModel.getData(), payload, &apos;normal&apos;);
        },
        remove: function (ecModel, api) {
            this.group.removeAll();
        },
        dispose: function () {
        }
    };
    var chartProto = Chart.prototype;
    chartProto.updateView = chartProto.updateLayout = chartProto.updateVisual = function (seriesModel, ecModel, api, payload) {
        this.render(seriesModel, ecModel, api, payload);
    };
    /**
     * Set state of single element
     * @param  {module:zrender/Element} el
     * @param  {string} state
     */
    function elSetState(el, state) {
        if (el) {
            el.trigger(state);
            if (el.type === &apos;group&apos;) {
                for (var i = 0; i &lt; el.childCount(); i++) {
                    elSetState(el.childAt(i), state);
                }
            }
        }
    }
    /**
     * @param  {module:echarts/data/List} data
     * @param  {Object} payload
     * @param  {string} state &apos;normal&apos;|&apos;emphasis&apos;
     * @inner
     */
    function toggleHighlight(data, payload, state) {
        var dataIndex = payload &amp;&amp; payload.dataIndex;
        var name = payload &amp;&amp; payload.name;
        if (dataIndex != null) {
            var dataIndices = dataIndex instanceof Array ? dataIndex : [dataIndex];
            for (var i = 0, len = dataIndices.length; i &lt; len; i++) {
                elSetState(data.getItemGraphicEl(dataIndices[i]), state);
            }
        } else if (name) {
            var names = name instanceof Array ? name : [name];
            for (var i = 0, len = names.length; i &lt; len; i++) {
                var dataIndex = data.indexOfName(names[i]);
                elSetState(data.getItemGraphicEl(dataIndex), state);
            }
        } else {
            data.eachItemGraphicEl(function (el) {
                elSetState(el, state);
            });
        }
    }
    // Enable Chart.extend.
    clazzUtil.enableClassExtend(Chart);
    // Add capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.
    clazzUtil.enableClassManagement(Chart, { registerWhenExtend: true });
    return Chart;
});
define(&apos;echarts/util/graphic&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;zrender/tool/path&apos;, &apos;zrender/graphic/Path&apos;, &apos;zrender/tool/color&apos;, &apos;zrender/core/matrix&apos;, &apos;zrender/core/vector&apos;, &apos;zrender/graphic/Gradient&apos;, &apos;zrender/container/Group&apos;, &apos;zrender/graphic/Image&apos;, &apos;zrender/graphic/Text&apos;, &apos;zrender/graphic/shape/Circle&apos;, &apos;zrender/graphic/shape/Sector&apos;, &apos;zrender/graphic/shape/Ring&apos;, &apos;zrender/graphic/shape/Polygon&apos;, &apos;zrender/graphic/shape/Polyline&apos;, &apos;zrender/graphic/shape/Rect&apos;, &apos;zrender/graphic/shape/Line&apos;, &apos;zrender/graphic/shape/BezierCurve&apos;, &apos;zrender/graphic/shape/Arc&apos;, &apos;zrender/graphic/CompoundPath&apos;, &apos;zrender/graphic/LinearGradient&apos;, &apos;zrender/graphic/RadialGradient&apos;, &apos;zrender/core/BoundingRect&apos;], function (require) {
    &apos;use strict&apos;;
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var pathTool = require(&apos;zrender/tool/path&apos;);
    var round = Math.round;
    var Path = require(&apos;zrender/graphic/Path&apos;);
    var colorTool = require(&apos;zrender/tool/color&apos;);
    var matrix = require(&apos;zrender/core/matrix&apos;);
    var vector = require(&apos;zrender/core/vector&apos;);
    var Gradient = require(&apos;zrender/graphic/Gradient&apos;);
    var graphic = {};
    graphic.Group = require(&apos;zrender/container/Group&apos;);
    graphic.Image = require(&apos;zrender/graphic/Image&apos;);
    graphic.Text = require(&apos;zrender/graphic/Text&apos;);
    graphic.Circle = require(&apos;zrender/graphic/shape/Circle&apos;);
    graphic.Sector = require(&apos;zrender/graphic/shape/Sector&apos;);
    graphic.Ring = require(&apos;zrender/graphic/shape/Ring&apos;);
    graphic.Polygon = require(&apos;zrender/graphic/shape/Polygon&apos;);
    graphic.Polyline = require(&apos;zrender/graphic/shape/Polyline&apos;);
    graphic.Rect = require(&apos;zrender/graphic/shape/Rect&apos;);
    graphic.Line = require(&apos;zrender/graphic/shape/Line&apos;);
    graphic.BezierCurve = require(&apos;zrender/graphic/shape/BezierCurve&apos;);
    graphic.Arc = require(&apos;zrender/graphic/shape/Arc&apos;);
    graphic.CompoundPath = require(&apos;zrender/graphic/CompoundPath&apos;);
    graphic.LinearGradient = require(&apos;zrender/graphic/LinearGradient&apos;);
    graphic.RadialGradient = require(&apos;zrender/graphic/RadialGradient&apos;);
    graphic.BoundingRect = require(&apos;zrender/core/BoundingRect&apos;);
    /**
     * Extend shape with parameters
     */
    graphic.extendShape = function (opts) {
        return Path.extend(opts);
    };
    /**
     * Extend path
     */
    graphic.extendPath = function (pathData, opts) {
        return pathTool.extendFromString(pathData, opts);
    };
    /**
     * Create a path element from path data string
     * @param {string} pathData
     * @param {Object} opts
     * @param {module:zrender/core/BoundingRect} rect
     * @param {string} [layout=cover] &apos;center&apos; or &apos;cover&apos;
     */
    graphic.makePath = function (pathData, opts, rect, layout) {
        var path = pathTool.createFromString(pathData, opts);
        var boundingRect = path.getBoundingRect();
        if (rect) {
            var aspect = boundingRect.width / boundingRect.height;
            if (layout === &apos;center&apos;) {
                // Set rect to center, keep width / height ratio.
                var width = rect.height * aspect;
                var height;
                if (width <= 0="" 1="" 2="==" rect.width)="" {="" height="rect.height;" }="" else="" width="rect.width;" aspect;="" var="" cx="rect.x" +="" rect.width="" 2;="" cy="rect.y" rect.height="" rect.x="cx" -="" rect.y="cy" this.resizepath(path,="" rect);="" return="" path;="" };="" graphic.mergepath="pathTool.mergePath," graphic.resizepath="function" (path,="" rect)="" if="" (!path.applytransform)="" return;="" pathrect="path.getBoundingRect();" m="pathRect.calculateTransform(rect);" path.applytransform(m);="" **="" *="" sub="" pixel="" optimize="" line="" for="" canvas="" @param="" {object}="" param="" [param.shape]="" {number}="" [param.shape.x1]="" [param.shape.y1]="" [param.shape.x2]="" [param.shape.y2]="" [param.style]="" [param.style.linewidth]="" @return="" modified="" graphic.subpixeloptimizeline="function" (param)="" subpixeloptimize="graphic.subPixelOptimize;" shape="param.shape;" linewidth="param.style.lineWidth;" (round(shape.x1="" 2)="==" round(shape.x2="" 2))="" shape.x1="shape.x2" =="" subpixeloptimize(shape.x1,="" linewidth,="" true);="" (round(shape.y1="" round(shape.y2="" shape.y1="shape.y2" subpixeloptimize(shape.y1,="" param;="" rect="" [param.shape.x]="" [param.shape.y]="" [param.shape.width]="" [param.shape.height]="" graphic.subpixeloptimizerect="function" originx="shape.x;" originy="shape.y;" originwidth="shape.width;" originheight="shape.height;" shape.x="subPixelOptimize(shape.x," shape.y="subPixelOptimize(shape.y," shape.width="Math.max(subPixelOptimize(originX" originwidth,="" false)="" shape.x,="" ?="" :="" 1);="" shape.height="Math.max(subPixelOptimize(originY" originheight,="" shape.y,="" position="" coordinate,="" such="" as="" x,="" y="" should="" be="" nonnegative="" integer.="" {boolean="}" positiveornegative="" default false="" (negative).="" optimized="" position.="" graphic.subpixeloptimize="function" (position,="" positiveornegative)="" assure="" that="" (position="" is="" near="" integer="" edge,="" otherwise="" will="" fuzzy="" in="" canvas.="" doubledposition="round(position" 2);="" (doubledposition="" round(linewidth))="" %="" (positiveornegative="" -1))="" function="" hasfillorstroke(fillorstroke)="" fillorstroke="" !="null" &&="" ;="" liftcolor(color)="" typeof="" color="==" 'string'="" colortool.lift(color,="" -0.1)="" color;="" @private="" cacheelementstl(el)="" (el.__hoverstldirty)="" stroke="el.style.stroke;" fill="el.style.fill;" create="" hoverstyle="" on="" mouseover="" hoverstyle.fill="hoverStyle.fill" ||="" (hasfillorstroke(fill)="" liftcolor(fill)="" null);="" hoverstyle.stroke="hoverStyle.stroke" (hasfillorstroke(stroke)="" liftcolor(stroke)="" normalstyle="{};" (var="" name="" hoverstyle)="" (hoverstyle.hasownproperty(name))="" normalstyle[name]="el.style[name];" el.__normalstl="normalStyle;" el.__hoverstldirty="false;" dosingleenterhover(el)="" (el.__ishover)="" cacheelementstl(el);="" (el.usehoverlayer)="" el.__zr="" el.__zr.addhover(el,="" el.__hoverstl);="" el.setstyle(el.__hoverstl);="" el.z2="" el.__ishover="true;" @inner="" dosingleleavehover(el)="" (!el.__ishover)="" normalstl="el.__normalStl;" el.__zr.removehover(el);="" el.setstyle(normalstl);="" doenterhover(el)="" el.type="==" 'group'="" el.traverse(function="" (child)="" (child.type="" 'group')="" dosingleenterhover(child);="" })="" dosingleenterhover(el);="" doleavehover(el)="" dosingleleavehover(child);="" dosingleleavehover(el);="" setelementhoverstl(el,="" hoverstl)="" element="" has="" sepcified="" hoverstyle,="" then="" use="" it="" instead="" of="" given="" often="" used="" when="" item="" group="" a="" label="" and="" it's="" different="" el.__hoverstl="el.hoverStyle" hoverstl="" {};="" onelementmouseover()="" only="" not="" emphasis="" status="" !this.__isemphasis="" doenterhover(this);="" onelementmouseout()="" doleavehover(this);="" enteremphasis()="" this.__isemphasis="true;" leaveemphasis()="" set="" hover="" style="" {module:zrender="" element}="" el="" [hoverstyle]="" graphic.sethoverstyle="function" (el,="" setelementhoverstl(child,="" hoverstyle);="" remove="" previous="" bound="" handlers="" el.on('mouseover',="" onelementmouseover).on('mouseout',="" onelementmouseout);="" emphasis,="" normal="" can="" triggered="" manually="" el.on('emphasis',="" enteremphasis).on('normal',="" leaveemphasis);="" text="" option="" the="" textstyle="" {module:echarts="" model="" model}="" labelmodel="" {string}="" graphic.settext="function" (textstyle,="" labelmodel,="" color)="" labelposition="labelModel.getShallow(&apos;position&apos;)" 'inside';="" labelcolor="labelPosition.indexOf(&apos;inside&apos;)">= 0 ? &apos;white&apos; : color;
        var textStyleModel = labelModel.getModel(&apos;textStyle&apos;);
        zrUtil.extend(textStyle, {
            textDistance: labelModel.getShallow(&apos;distance&apos;) || 5,
            textFont: textStyleModel.getFont(),
            textPosition: labelPosition,
            textFill: textStyleModel.getTextColor() || labelColor
        });
    };
    function animateOrSetProps(isUpdate, el, props, animatableModel, dataIndex, cb) {
        if (typeof dataIndex === &apos;function&apos;) {
            cb = dataIndex;
            dataIndex = null;
        }
        var animationEnabled = animatableModel &amp;&amp; (animatableModel.ifEnableAnimation ? animatableModel.ifEnableAnimation() : animatableModel.getShallow(&apos;animation&apos;));
        if (animationEnabled) {
            var postfix = isUpdate ? &apos;Update&apos; : &apos;&apos;;
            var duration = animatableModel &amp;&amp; animatableModel.getShallow(&apos;animationDuration&apos; + postfix);
            var animationEasing = animatableModel &amp;&amp; animatableModel.getShallow(&apos;animationEasing&apos; + postfix);
            var animationDelay = animatableModel &amp;&amp; animatableModel.getShallow(&apos;animationDelay&apos; + postfix);
            if (typeof animationDelay === &apos;function&apos;) {
                animationDelay = animationDelay(dataIndex);
            }
            duration &gt; 0 ? el.animateTo(props, duration, animationDelay || 0, animationEasing, cb) : (el.attr(props), cb &amp;&amp; cb());
        } else {
            el.attr(props);
            cb &amp;&amp; cb();
        }
    }
    /**
     * Update graphic element properties with or without animation according to the configuration in series
     * @param {module:zrender/Element} el
     * @param {Object} props
     * @param {module:echarts/model/Model} [animatableModel]
     * @param {number} [dataIndex]
     * @param {Function} [cb]
     * @example
     *     graphic.updateProps(el, {
     *         position: [100, 100]
     *     }, seriesModel, dataIndex, function () { console.log(&apos;Animation done!&apos;); });
     *     // Or
     *     graphic.updateProps(el, {
     *         position: [100, 100]
     *     }, seriesModel, function () { console.log(&apos;Animation done!&apos;); });
     */
    graphic.updateProps = function (el, props, animatableModel, dataIndex, cb) {
        animateOrSetProps(true, el, props, animatableModel, dataIndex, cb);
    };
    /**
     * Init graphic element properties with or without animation according to the configuration in series
     * @param {module:zrender/Element} el
     * @param {Object} props
     * @param {module:echarts/model/Model} [animatableModel]
     * @param {number} [dataIndex]
     * @param {Function} cb
     */
    graphic.initProps = function (el, props, animatableModel, dataIndex, cb) {
        animateOrSetProps(false, el, props, animatableModel, dataIndex, cb);
    };
    /**
     * Get transform matrix of target (param target),
     * in coordinate of its ancestor (param ancestor)
     *
     * @param {module:zrender/mixin/Transformable} target
     * @param {module:zrender/mixin/Transformable} [ancestor]
     */
    graphic.getTransform = function (target, ancestor) {
        var mat = matrix.identity([]);
        while (target &amp;&amp; target !== ancestor) {
            matrix.mul(mat, target.getLocalTransform(), mat);
            target = target.parent;
        }
        return mat;
    };
    /**
     * Apply transform to an vertex.
     * @param {Array.<number>} vertex [x, y]
     * @param {Array.<number>} transform Transform matrix: like [1, 0, 0, 1, 0, 0]
     * @param {boolean=} invert Whether use invert matrix.
     * @return {Array.<number>} [x, y]
     */
    graphic.applyTransform = function (vertex, transform, invert) {
        if (invert) {
            transform = matrix.invert([], transform);
        }
        return vector.applyTransform([], vertex, transform);
    };
    /**
     * @param {string} direction &apos;left&apos; &apos;right&apos; &apos;top&apos; &apos;bottom&apos;
     * @param {Array.<number>} transform Transform matrix: like [1, 0, 0, 1, 0, 0]
     * @param {boolean=} invert Whether use invert matrix.
     * @return {string} Transformed direction. &apos;left&apos; &apos;right&apos; &apos;top&apos; &apos;bottom&apos;
     */
    graphic.transformDirection = function (direction, transform, invert) {
        // Pick a base, ensure that transform result will not be (0, 0).
        var hBase = transform[4] === 0 || transform[5] === 0 || transform[0] === 0 ? 1 : Math.abs(2 * transform[4] / transform[0]);
        var vBase = transform[4] === 0 || transform[5] === 0 || transform[2] === 0 ? 1 : Math.abs(2 * transform[4] / transform[2]);
        var vertex = [
                direction === &apos;left&apos; ? -hBase : direction === &apos;right&apos; ? hBase : 0,
                direction === &apos;top&apos; ? -vBase : direction === &apos;bottom&apos; ? vBase : 0
            ];
        vertex = graphic.applyTransform(vertex, transform, invert);
        return Math.abs(vertex[0]) &gt; Math.abs(vertex[1]) ? vertex[0] &gt; 0 ? &apos;right&apos; : &apos;left&apos; : vertex[1] &gt; 0 ? &apos;bottom&apos; : &apos;top&apos;;
    };
    /**
     * Apply group transition animation from g1 to g2
     */
    graphic.groupTransition = function (g1, g2, animatableModel, cb) {
        if (!g1 || !g2) {
            return;
        }
        function getElMap(g) {
            var elMap = {};
            g.traverse(function (el) {
                if (!el.isGroup &amp;&amp; el.anid) {
                    elMap[el.anid] = el;
                }
            });
            return elMap;
        }
        function getAnimatableProps(el) {
            var obj = {
                    position: vector.clone(el.position),
                    rotation: el.rotation
                };
            if (el.shape) {
                obj.shape = zrUtil.extend({}, el.shape);
            }
            return obj;
        }
        var elMap1 = getElMap(g1);
        g2.traverse(function (el) {
            if (!el.isGroup &amp;&amp; el.anid) {
                var oldEl = elMap1[el.anid];
                if (oldEl) {
                    var newProp = getAnimatableProps(el);
                    el.attr(getAnimatableProps(oldEl));
                    graphic.updateProps(el, newProp, animatableModel, el.dataIndex);
                }    // else {
                     //     if (el.previousProps) {
                     //         graphic.updateProps
                     //     }
                     // }
            }
        });
    };
    return graphic;
});
define(&apos;echarts/view/Component&apos;, [&apos;require&apos;, &apos;zrender/container/Group&apos;, &apos;../util/component&apos;, &apos;../util/clazz&apos;], function (require) {
    var Group = require(&apos;zrender/container/Group&apos;);
    var componentUtil = require(&apos;../util/component&apos;);
    var clazzUtil = require(&apos;../util/clazz&apos;);
    var Component = function () {
        /**
         * @type {module:zrender/container/Group}
         * @readOnly
         */
        this.group = new Group();
        /**
         * @type {string}
         * @readOnly
         */
        this.uid = componentUtil.getUID(&apos;viewComponent&apos;);
    };
    Component.prototype = {
        constructor: Component,
        init: function (ecModel, api) {
        },
        render: function (componentModel, ecModel, api, payload) {
        },
        dispose: function () {
        }
    };
    var componentProto = Component.prototype;
    componentProto.updateView = componentProto.updateLayout = componentProto.updateVisual = function (seriesModel, ecModel, api, payload) {
    };
    // Enable Component.extend.
    clazzUtil.enableClassExtend(Component);
    // Enable capability of registerClass, getClass, hasClass, registerSubTypeDefaulter and so on.
    clazzUtil.enableClassManagement(Component, { registerWhenExtend: true });
    return Component;
});
define(&apos;zrender/zrender&apos;, [&apos;require&apos;, &apos;./core/guid&apos;, &apos;./core/env&apos;, &apos;./Handler&apos;, &apos;./Storage&apos;, &apos;./animation/Animation&apos;, &apos;./dom/HandlerProxy&apos;, &apos;./Painter&apos;], function (require) {
    var guid = require(&apos;./core/guid&apos;);
    var env = require(&apos;./core/env&apos;);
    var Handler = require(&apos;./Handler&apos;);
    var Storage = require(&apos;./Storage&apos;);
    var Animation = require(&apos;./animation/Animation&apos;);
    var HandlerProxy = require(&apos;./dom/HandlerProxy&apos;);
    var useVML = !env.canvasSupported;
    var painterCtors = { canvas: require(&apos;./Painter&apos;) };
    var instances = {};
    // ZRender&#x5B9E;&#x4F8B;map&#x7D22;&#x5F15;
    var zrender = {};
    /**
     * @type {string}
     */
    zrender.version = &apos;3.1.2&apos;;
    /**
     * Initializing a zrender instance
     * @param {HTMLElement} dom
     * @param {Object} opts
     * @param {string} [opts.renderer=&apos;canvas&apos;] &apos;canvas&apos; or &apos;svg&apos;
     * @param {number} [opts.devicePixelRatio]
     * @return {module:zrender/ZRender}
     */
    zrender.init = function (dom, opts) {
        var zr = new ZRender(guid(), dom, opts);
        instances[zr.id] = zr;
        return zr;
    };
    /**
     * Dispose zrender instance
     * @param {module:zrender/ZRender} zr
     */
    zrender.dispose = function (zr) {
        if (zr) {
            zr.dispose();
        } else {
            for (var key in instances) {
                instances[key].dispose();
            }
            instances = {};
        }
        return zrender;
    };
    /**
     * Get zrender instance by id
     * @param {string} id zrender instance id
     * @return {module:zrender/ZRender}
     */
    zrender.getInstance = function (id) {
        return instances[id];
    };
    zrender.registerPainter = function (name, Ctor) {
        painterCtors[name] = Ctor;
    };
    function delInstance(id) {
        delete instances[id];
    }
    /**
     * @module zrender/ZRender
     */
    /**
     * @constructor
     * @alias module:zrender/ZRender
     * @param {string} id
     * @param {HTMLDomElement} dom
     * @param {Object} opts
     * @param {string} [opts.renderer=&apos;canvas&apos;] &apos;canvas&apos; or &apos;svg&apos;
     * @param {number} [opts.devicePixelRatio]
     */
    var ZRender = function (id, dom, opts) {
        opts = opts || {};
        /**
         * @type {HTMLDomElement}
         */
        this.dom = dom;
        /**
         * @type {string}
         */
        this.id = id;
        var self = this;
        var storage = new Storage();
        var rendererType = opts.renderer;
        if (useVML) {
            if (!painterCtors.vml) {
                throw new Error(&apos;You need to require \&apos;zrender/vml/vml\&apos; to support IE8&apos;);
            }
            rendererType = &apos;vml&apos;;
        } else if (!rendererType || !painterCtors[rendererType]) {
            rendererType = &apos;canvas&apos;;
        }
        var painter = new painterCtors[rendererType](dom, storage, opts);
        this.storage = storage;
        this.painter = painter;
        var handerProxy = !env.node ? new HandlerProxy(painter.getViewportRoot()) : null;
        this.handler = new Handler(storage, painter, handerProxy);
        /**
         * @type {module:zrender/animation/Animation}
         */
        this.animation = new Animation({
            stage: {
                update: function () {
                    if (self._needsRefresh) {
                        self.refreshImmediately();
                    }
                    if (self._needsRefreshHover) {
                        self.refreshHoverImmediately();
                    }
                }
            }
        });
        this.animation.start();
        /**
         * @type {boolean}
         * @private
         */
        this._needsRefresh;
        // &#x4FEE;&#x6539; storage.delFromMap, &#x6BCF;&#x6B21;&#x5220;&#x9664;&#x5143;&#x7D20;&#x4E4B;&#x524D;&#x5220;&#x9664;&#x52A8;&#x753B;
        // FIXME &#x6709;&#x70B9;ugly
        var oldDelFromMap = storage.delFromMap;
        var oldAddToMap = storage.addToMap;
        storage.delFromMap = function (elId) {
            var el = storage.get(elId);
            oldDelFromMap.call(storage, elId);
            el &amp;&amp; el.removeSelfFromZr(self);
        };
        storage.addToMap = function (el) {
            oldAddToMap.call(storage, el);
            el.addSelfToZr(self);
        };
    };
    ZRender.prototype = {
        constructor: ZRender,
        getId: function () {
            return this.id;
        },
        add: function (el) {
            this.storage.addRoot(el);
            this._needsRefresh = true;
        },
        remove: function (el) {
            this.storage.delRoot(el);
            this._needsRefresh = true;
        },
        configLayer: function (zLevel, config) {
            this.painter.configLayer(zLevel, config);
            this._needsRefresh = true;
        },
        refreshImmediately: function () {
            // Clear needsRefresh ahead to avoid something wrong happens in refresh
            // Or it will cause zrender refreshes again and again.
            this._needsRefresh = false;
            this.painter.refresh();
            /**
             * Avoid trigger zr.refresh in Element#beforeUpdate hook
             */
            this._needsRefresh = false;
        },
        refresh: function () {
            this._needsRefresh = true;
        },
        addHover: function (el, style) {
            if (this.painter.addHover) {
                this.painter.addHover(el, style);
                this.refreshHover();
            }
        },
        removeHover: function (el) {
            if (this.painter.removeHover) {
                this.painter.removeHover(el);
                this.refreshHover();
            }
        },
        clearHover: function () {
            if (this.painter.clearHover) {
                this.painter.clearHover();
                this.refreshHover();
            }
        },
        refreshHover: function () {
            this._needsRefreshHover = true;
        },
        refreshHoverImmediately: function () {
            this._needsRefreshHover = false;
            this.painter.refreshHover &amp;&amp; this.painter.refreshHover();
        },
        resize: function () {
            this.painter.resize();
            this.handler.resize();
        },
        clearAnimation: function () {
            this.animation.clear();
        },
        getWidth: function () {
            return this.painter.getWidth();
        },
        getHeight: function () {
            return this.painter.getHeight();
        },
        pathToImage: function (e, width, height) {
            var id = guid();
            return this.painter.pathToImage(id, e, width, height);
        },
        setCursorStyle: function (cursorStyle) {
            this.handler.setCursorStyle(cursorStyle);
        },
        on: function (eventName, eventHandler, context) {
            this.handler.on(eventName, eventHandler, context);
        },
        off: function (eventName, eventHandler) {
            this.handler.off(eventName, eventHandler);
        },
        trigger: function (eventName, event) {
            this.handler.trigger(eventName, event);
        },
        clear: function () {
            this.storage.delRoot();
            this.painter.clear();
        },
        dispose: function () {
            this.animation.stop();
            this.clear();
            this.storage.dispose();
            this.painter.dispose();
            this.handler.dispose();
            this.animation = this.storage = this.painter = this.handler = null;
            delInstance(this.id);
        }
    };
    return zrender;
});
define(&apos;zrender/tool/color&apos;, [&apos;require&apos;], function (require) {
    var kCSSColorTable = {
            &apos;transparent&apos;: [
                0,
                0,
                0,
                0
            ],
            &apos;aliceblue&apos;: [
                240,
                248,
                255,
                1
            ],
            &apos;antiquewhite&apos;: [
                250,
                235,
                215,
                1
            ],
            &apos;aqua&apos;: [
                0,
                255,
                255,
                1
            ],
            &apos;aquamarine&apos;: [
                127,
                255,
                212,
                1
            ],
            &apos;azure&apos;: [
                240,
                255,
                255,
                1
            ],
            &apos;beige&apos;: [
                245,
                245,
                220,
                1
            ],
            &apos;bisque&apos;: [
                255,
                228,
                196,
                1
            ],
            &apos;black&apos;: [
                0,
                0,
                0,
                1
            ],
            &apos;blanchedalmond&apos;: [
                255,
                235,
                205,
                1
            ],
            &apos;blue&apos;: [
                0,
                0,
                255,
                1
            ],
            &apos;blueviolet&apos;: [
                138,
                43,
                226,
                1
            ],
            &apos;brown&apos;: [
                165,
                42,
                42,
                1
            ],
            &apos;burlywood&apos;: [
                222,
                184,
                135,
                1
            ],
            &apos;cadetblue&apos;: [
                95,
                158,
                160,
                1
            ],
            &apos;chartreuse&apos;: [
                127,
                255,
                0,
                1
            ],
            &apos;chocolate&apos;: [
                210,
                105,
                30,
                1
            ],
            &apos;coral&apos;: [
                255,
                127,
                80,
                1
            ],
            &apos;cornflowerblue&apos;: [
                100,
                149,
                237,
                1
            ],
            &apos;cornsilk&apos;: [
                255,
                248,
                220,
                1
            ],
            &apos;crimson&apos;: [
                220,
                20,
                60,
                1
            ],
            &apos;cyan&apos;: [
                0,
                255,
                255,
                1
            ],
            &apos;darkblue&apos;: [
                0,
                0,
                139,
                1
            ],
            &apos;darkcyan&apos;: [
                0,
                139,
                139,
                1
            ],
            &apos;darkgoldenrod&apos;: [
                184,
                134,
                11,
                1
            ],
            &apos;darkgray&apos;: [
                169,
                169,
                169,
                1
            ],
            &apos;darkgreen&apos;: [
                0,
                100,
                0,
                1
            ],
            &apos;darkgrey&apos;: [
                169,
                169,
                169,
                1
            ],
            &apos;darkkhaki&apos;: [
                189,
                183,
                107,
                1
            ],
            &apos;darkmagenta&apos;: [
                139,
                0,
                139,
                1
            ],
            &apos;darkolivegreen&apos;: [
                85,
                107,
                47,
                1
            ],
            &apos;darkorange&apos;: [
                255,
                140,
                0,
                1
            ],
            &apos;darkorchid&apos;: [
                153,
                50,
                204,
                1
            ],
            &apos;darkred&apos;: [
                139,
                0,
                0,
                1
            ],
            &apos;darksalmon&apos;: [
                233,
                150,
                122,
                1
            ],
            &apos;darkseagreen&apos;: [
                143,
                188,
                143,
                1
            ],
            &apos;darkslateblue&apos;: [
                72,
                61,
                139,
                1
            ],
            &apos;darkslategray&apos;: [
                47,
                79,
                79,
                1
            ],
            &apos;darkslategrey&apos;: [
                47,
                79,
                79,
                1
            ],
            &apos;darkturquoise&apos;: [
                0,
                206,
                209,
                1
            ],
            &apos;darkviolet&apos;: [
                148,
                0,
                211,
                1
            ],
            &apos;deeppink&apos;: [
                255,
                20,
                147,
                1
            ],
            &apos;deepskyblue&apos;: [
                0,
                191,
                255,
                1
            ],
            &apos;dimgray&apos;: [
                105,
                105,
                105,
                1
            ],
            &apos;dimgrey&apos;: [
                105,
                105,
                105,
                1
            ],
            &apos;dodgerblue&apos;: [
                30,
                144,
                255,
                1
            ],
            &apos;firebrick&apos;: [
                178,
                34,
                34,
                1
            ],
            &apos;floralwhite&apos;: [
                255,
                250,
                240,
                1
            ],
            &apos;forestgreen&apos;: [
                34,
                139,
                34,
                1
            ],
            &apos;fuchsia&apos;: [
                255,
                0,
                255,
                1
            ],
            &apos;gainsboro&apos;: [
                220,
                220,
                220,
                1
            ],
            &apos;ghostwhite&apos;: [
                248,
                248,
                255,
                1
            ],
            &apos;gold&apos;: [
                255,
                215,
                0,
                1
            ],
            &apos;goldenrod&apos;: [
                218,
                165,
                32,
                1
            ],
            &apos;gray&apos;: [
                128,
                128,
                128,
                1
            ],
            &apos;green&apos;: [
                0,
                128,
                0,
                1
            ],
            &apos;greenyellow&apos;: [
                173,
                255,
                47,
                1
            ],
            &apos;grey&apos;: [
                128,
                128,
                128,
                1
            ],
            &apos;honeydew&apos;: [
                240,
                255,
                240,
                1
            ],
            &apos;hotpink&apos;: [
                255,
                105,
                180,
                1
            ],
            &apos;indianred&apos;: [
                205,
                92,
                92,
                1
            ],
            &apos;indigo&apos;: [
                75,
                0,
                130,
                1
            ],
            &apos;ivory&apos;: [
                255,
                255,
                240,
                1
            ],
            &apos;khaki&apos;: [
                240,
                230,
                140,
                1
            ],
            &apos;lavender&apos;: [
                230,
                230,
                250,
                1
            ],
            &apos;lavenderblush&apos;: [
                255,
                240,
                245,
                1
            ],
            &apos;lawngreen&apos;: [
                124,
                252,
                0,
                1
            ],
            &apos;lemonchiffon&apos;: [
                255,
                250,
                205,
                1
            ],
            &apos;lightblue&apos;: [
                173,
                216,
                230,
                1
            ],
            &apos;lightcoral&apos;: [
                240,
                128,
                128,
                1
            ],
            &apos;lightcyan&apos;: [
                224,
                255,
                255,
                1
            ],
            &apos;lightgoldenrodyellow&apos;: [
                250,
                250,
                210,
                1
            ],
            &apos;lightgray&apos;: [
                211,
                211,
                211,
                1
            ],
            &apos;lightgreen&apos;: [
                144,
                238,
                144,
                1
            ],
            &apos;lightgrey&apos;: [
                211,
                211,
                211,
                1
            ],
            &apos;lightpink&apos;: [
                255,
                182,
                193,
                1
            ],
            &apos;lightsalmon&apos;: [
                255,
                160,
                122,
                1
            ],
            &apos;lightseagreen&apos;: [
                32,
                178,
                170,
                1
            ],
            &apos;lightskyblue&apos;: [
                135,
                206,
                250,
                1
            ],
            &apos;lightslategray&apos;: [
                119,
                136,
                153,
                1
            ],
            &apos;lightslategrey&apos;: [
                119,
                136,
                153,
                1
            ],
            &apos;lightsteelblue&apos;: [
                176,
                196,
                222,
                1
            ],
            &apos;lightyellow&apos;: [
                255,
                255,
                224,
                1
            ],
            &apos;lime&apos;: [
                0,
                255,
                0,
                1
            ],
            &apos;limegreen&apos;: [
                50,
                205,
                50,
                1
            ],
            &apos;linen&apos;: [
                250,
                240,
                230,
                1
            ],
            &apos;magenta&apos;: [
                255,
                0,
                255,
                1
            ],
            &apos;maroon&apos;: [
                128,
                0,
                0,
                1
            ],
            &apos;mediumaquamarine&apos;: [
                102,
                205,
                170,
                1
            ],
            &apos;mediumblue&apos;: [
                0,
                0,
                205,
                1
            ],
            &apos;mediumorchid&apos;: [
                186,
                85,
                211,
                1
            ],
            &apos;mediumpurple&apos;: [
                147,
                112,
                219,
                1
            ],
            &apos;mediumseagreen&apos;: [
                60,
                179,
                113,
                1
            ],
            &apos;mediumslateblue&apos;: [
                123,
                104,
                238,
                1
            ],
            &apos;mediumspringgreen&apos;: [
                0,
                250,
                154,
                1
            ],
            &apos;mediumturquoise&apos;: [
                72,
                209,
                204,
                1
            ],
            &apos;mediumvioletred&apos;: [
                199,
                21,
                133,
                1
            ],
            &apos;midnightblue&apos;: [
                25,
                25,
                112,
                1
            ],
            &apos;mintcream&apos;: [
                245,
                255,
                250,
                1
            ],
            &apos;mistyrose&apos;: [
                255,
                228,
                225,
                1
            ],
            &apos;moccasin&apos;: [
                255,
                228,
                181,
                1
            ],
            &apos;navajowhite&apos;: [
                255,
                222,
                173,
                1
            ],
            &apos;navy&apos;: [
                0,
                0,
                128,
                1
            ],
            &apos;oldlace&apos;: [
                253,
                245,
                230,
                1
            ],
            &apos;olive&apos;: [
                128,
                128,
                0,
                1
            ],
            &apos;olivedrab&apos;: [
                107,
                142,
                35,
                1
            ],
            &apos;orange&apos;: [
                255,
                165,
                0,
                1
            ],
            &apos;orangered&apos;: [
                255,
                69,
                0,
                1
            ],
            &apos;orchid&apos;: [
                218,
                112,
                214,
                1
            ],
            &apos;palegoldenrod&apos;: [
                238,
                232,
                170,
                1
            ],
            &apos;palegreen&apos;: [
                152,
                251,
                152,
                1
            ],
            &apos;paleturquoise&apos;: [
                175,
                238,
                238,
                1
            ],
            &apos;palevioletred&apos;: [
                219,
                112,
                147,
                1
            ],
            &apos;papayawhip&apos;: [
                255,
                239,
                213,
                1
            ],
            &apos;peachpuff&apos;: [
                255,
                218,
                185,
                1
            ],
            &apos;peru&apos;: [
                205,
                133,
                63,
                1
            ],
            &apos;pink&apos;: [
                255,
                192,
                203,
                1
            ],
            &apos;plum&apos;: [
                221,
                160,
                221,
                1
            ],
            &apos;powderblue&apos;: [
                176,
                224,
                230,
                1
            ],
            &apos;purple&apos;: [
                128,
                0,
                128,
                1
            ],
            &apos;red&apos;: [
                255,
                0,
                0,
                1
            ],
            &apos;rosybrown&apos;: [
                188,
                143,
                143,
                1
            ],
            &apos;royalblue&apos;: [
                65,
                105,
                225,
                1
            ],
            &apos;saddlebrown&apos;: [
                139,
                69,
                19,
                1
            ],
            &apos;salmon&apos;: [
                250,
                128,
                114,
                1
            ],
            &apos;sandybrown&apos;: [
                244,
                164,
                96,
                1
            ],
            &apos;seagreen&apos;: [
                46,
                139,
                87,
                1
            ],
            &apos;seashell&apos;: [
                255,
                245,
                238,
                1
            ],
            &apos;sienna&apos;: [
                160,
                82,
                45,
                1
            ],
            &apos;silver&apos;: [
                192,
                192,
                192,
                1
            ],
            &apos;skyblue&apos;: [
                135,
                206,
                235,
                1
            ],
            &apos;slateblue&apos;: [
                106,
                90,
                205,
                1
            ],
            &apos;slategray&apos;: [
                112,
                128,
                144,
                1
            ],
            &apos;slategrey&apos;: [
                112,
                128,
                144,
                1
            ],
            &apos;snow&apos;: [
                255,
                250,
                250,
                1
            ],
            &apos;springgreen&apos;: [
                0,
                255,
                127,
                1
            ],
            &apos;steelblue&apos;: [
                70,
                130,
                180,
                1
            ],
            &apos;tan&apos;: [
                210,
                180,
                140,
                1
            ],
            &apos;teal&apos;: [
                0,
                128,
                128,
                1
            ],
            &apos;thistle&apos;: [
                216,
                191,
                216,
                1
            ],
            &apos;tomato&apos;: [
                255,
                99,
                71,
                1
            ],
            &apos;turquoise&apos;: [
                64,
                224,
                208,
                1
            ],
            &apos;violet&apos;: [
                238,
                130,
                238,
                1
            ],
            &apos;wheat&apos;: [
                245,
                222,
                179,
                1
            ],
            &apos;white&apos;: [
                255,
                255,
                255,
                1
            ],
            &apos;whitesmoke&apos;: [
                245,
                245,
                245,
                1
            ],
            &apos;yellow&apos;: [
                255,
                255,
                0,
                1
            ],
            &apos;yellowgreen&apos;: [
                154,
                205,
                50,
                1
            ]
        };
    function clampCssByte(i) {
        // Clamp to integer 0 .. 255.
        i = Math.round(i);
        // Seems to be what Chrome does (vs truncation).
        return i &lt; 0 ? 0 : i &gt; 255 ? 255 : i;
    }
    function clampCssAngle(i) {
        // Clamp to integer 0 .. 360.
        i = Math.round(i);
        // Seems to be what Chrome does (vs truncation).
        return i &lt; 0 ? 0 : i &gt; 360 ? 360 : i;
    }
    function clampCssFloat(f) {
        // Clamp to float 0.0 .. 1.0.
        return f &lt; 0 ? 0 : f &gt; 1 ? 1 : f;
    }
    function parseCssInt(str) {
        // int or percentage.
        if (str.length &amp;&amp; str.charAt(str.length - 1) === &apos;%&apos;) {
            return clampCssByte(parseFloat(str) / 100 * 255);
        }
        return clampCssByte(parseInt(str, 10));
    }
    function parseCssFloat(str) {
        // float or percentage.
        if (str.length &amp;&amp; str.charAt(str.length - 1) === &apos;%&apos;) {
            return clampCssFloat(parseFloat(str) / 100);
        }
        return clampCssFloat(parseFloat(str));
    }
    function cssHueToRgb(m1, m2, h) {
        if (h &lt; 0) {
            h += 1;
        } else if (h &gt; 1) {
            h -= 1;
        }
        if (h * 6 &lt; 1) {
            return m1 + (m2 - m1) * h * 6;
        }
        if (h * 2 &lt; 1) {
            return m2;
        }
        if (h * 3 &lt; 2) {
            return m1 + (m2 - m1) * (2 / 3 - h) * 6;
        }
        return m1;
    }
    function lerp(a, b, p) {
        return a + (b - a) * p;
    }
    /**
     * @param {string} colorStr
     * @return {Array.<number>}
     * @memberOf module:zrender/util/color
     */
    function parse(colorStr) {
        if (!colorStr) {
            return;
        }
        // colorStr may be not string
        colorStr = colorStr + &apos;&apos;;
        // Remove all whitespace, not compliant, but should just be more accepting.
        var str = colorStr.replace(/ /g, &apos;&apos;).toLowerCase();
        // Color keywords (and transparent) lookup.
        if (str in kCSSColorTable) {
            return kCSSColorTable[str].slice();    // dup.
        }
        // #abc and #abc123 syntax.
        if (str.charAt(0) === &apos;#&apos;) {
            if (str.length === 4) {
                var iv = parseInt(str.substr(1), 16);
                // TODO(deanm): Stricter parsing.
                if (!(iv &gt;= 0 &amp;&amp; iv <= 4095))="" {="" return;="" covers="" nan.="" }="" return="" [="" (iv="" &="" 3840)="">&gt; 4 | (iv &amp; 3840) &gt;&gt; 8,
                    iv &amp; 240 | (iv &amp; 240) &gt;&gt; 4,
                    iv &amp; 15 | (iv &amp; 15) &lt;&lt; 4,
                    1
                ];
            } else if (str.length === 7) {
                var iv = parseInt(str.substr(1), 16);
                // TODO(deanm): Stricter parsing.
                if (!(iv &gt;= 0 &amp;&amp; iv <= 16777215))="" {="" return;="" covers="" nan.="" }="" return="" [="" (iv="" &="" 16711680)="">&gt; 16,
                    (iv &amp; 65280) &gt;&gt; 8,
                    iv &amp; 255,
                    1
                ];
            }
            return;
        }
        var op = str.indexOf(&apos;(&apos;), ep = str.indexOf(&apos;)&apos;);
        if (op !== -1 &amp;&amp; ep + 1 === str.length) {
            var fname = str.substr(0, op);
            var params = str.substr(op + 1, ep - (op + 1)).split(&apos;,&apos;);
            var alpha = 1;
            // To allow case fallthrough.
            switch (fname) {
            case &apos;rgba&apos;:
                if (params.length !== 4) {
                    return;
                }
                alpha = parseCssFloat(params.pop());
            // jshint ignore:line
            // Fall through.
            case &apos;rgb&apos;:
                if (params.length !== 3) {
                    return;
                }
                return [
                    parseCssInt(params[0]),
                    parseCssInt(params[1]),
                    parseCssInt(params[2]),
                    alpha
                ];
            case &apos;hsla&apos;:
                if (params.length !== 4) {
                    return;
                }
                params[3] = parseCssFloat(params[3]);
                return hsla2rgba(params);
            case &apos;hsl&apos;:
                if (params.length !== 3) {
                    return;
                }
                return hsla2rgba(params);
            default:
                return;
            }
        }
        return;
    }
    /**
     * @param {Array.<number>} hsla
     * @return {Array.<number>} rgba
     */
    function hsla2rgba(hsla) {
        var h = (parseFloat(hsla[0]) % 360 + 360) % 360 / 360;
        // 0 .. 1
        // NOTE(deanm): According to the CSS spec s/l should only be
        // percentages, but we don&apos;t bother and let float or percentage.
        var s = parseCssFloat(hsla[1]);
        var l = parseCssFloat(hsla[2]);
        var m2 = l <= 1="" 2="" 0.5="" ?="" l="" *="" (s="" +="" 1)="" :="" s="" -="" s;="" var="" m1="l" m2;="" rgba="[" clampcssbyte(csshuetorgb(m1,="" m2,="" h="" 3)="" 255),="" h)="" 255)="" ];="" if="" (hsla.length="==" 4)="" {="" rgba[3]="hsla[3];" }="" return="" rgba;="" **="" @param="" {array.<number="">} rgba
     * @return {Array.<number>} hsla
     */
    function rgba2hsla(rgba) {
        if (!rgba) {
            return;
        }
        // RGB from 0 to 255
        var R = rgba[0] / 255;
        var G = rgba[1] / 255;
        var B = rgba[2] / 255;
        var vMin = Math.min(R, G, B);
        // Min. value of RGB
        var vMax = Math.max(R, G, B);
        // Max. value of RGB
        var delta = vMax - vMin;
        // Delta RGB value
        var L = (vMax + vMin) / 2;
        var H;
        var S;
        // HSL results from 0 to 1
        if (delta === 0) {
            H = 0;
            S = 0;
        } else {
            if (L &lt; 0.5) {
                S = delta / (vMax + vMin);
            } else {
                S = delta / (2 - vMax - vMin);
            }
            var deltaR = ((vMax - R) / 6 + delta / 2) / delta;
            var deltaG = ((vMax - G) / 6 + delta / 2) / delta;
            var deltaB = ((vMax - B) / 6 + delta / 2) / delta;
            if (R === vMax) {
                H = deltaB - deltaG;
            } else if (G === vMax) {
                H = 1 / 3 + deltaR - deltaB;
            } else if (B === vMax) {
                H = 2 / 3 + deltaG - deltaR;
            }
            if (H &lt; 0) {
                H += 1;
            }
            if (H &gt; 1) {
                H -= 1;
            }
        }
        var hsla = [
                H * 360,
                S,
                L
            ];
        if (rgba[3] != null) {
            hsla.push(rgba[3]);
        }
        return hsla;
    }
    /**
     * @param {string} color
     * @param {number} level
     * @return {string}
     * @memberOf module:zrender/util/color
     */
    function lift(color, level) {
        var colorArr = parse(color);
        if (colorArr) {
            for (var i = 0; i &lt; 3; i++) {
                if (level &lt; 0) {
                    colorArr[i] = colorArr[i] * (1 - level) | 0;
                } else {
                    colorArr[i] = (255 - colorArr[i]) * level + colorArr[i] | 0;
                }
            }
            return stringify(colorArr, colorArr.length === 4 ? &apos;rgba&apos; : &apos;rgb&apos;);
        }
    }
    /**
     * @param {string} color
     * @return {string}
     * @memberOf module:zrender/util/color
     */
    function toHex(color, level) {
        var colorArr = parse(color);
        if (colorArr) {
            return ((1 &lt;&lt; 24) + (colorArr[0] &lt;&lt; 16) + (colorArr[1] &lt;&lt; 8) + +colorArr[2]).toString(16).slice(1);
        }
    }
    /**
     * Map value to color. Faster than mapToColor methods because color is represented by rgba array
     * @param {number} normalizedValue A float between 0 and 1.
     * @param {Array.<array.<number>&gt;} colors List of rgba color array
     * @param {Array.<number>} [out] Mapped gba color array
     * @return {Array.<number>}
     */
    function fastMapToColor(normalizedValue, colors, out) {
        if (!(colors &amp;&amp; colors.length) || !(normalizedValue &gt;= 0 &amp;&amp; normalizedValue <= 0="" 1))="" {="" return;="" }="" out="out" ||="" [="" 0,="" ];="" var="" value="normalizedValue" *="" (colors.length="" -="" 1);="" leftindex="Math.floor(value);" rightindex="Math.ceil(value);" leftcolor="colors[leftIndex];" rightcolor="colors[rightIndex];" dv="value" leftindex;="" out[0]="clampCssByte(lerp(leftColor[0]," rightcolor[0],="" dv));="" out[1]="clampCssByte(lerp(leftColor[1]," rightcolor[1],="" out[2]="clampCssByte(lerp(leftColor[2]," rightcolor[2],="" out[3]="clampCssByte(lerp(leftColor[3]," rightcolor[3],="" return="" out;="" **="" @param="" {number}="" normalizedvalue="" a="" float="" between="" and="" 1.="" {array.<string="">} colors Color list.
     * @param {boolean=} fullOutput Default false.
     * @return {(string|Object)} Result color. If fullOutput,
     *                           return {color: ..., leftIndex: ..., rightIndex: ..., value: ...},
     * @memberOf module:zrender/util/color
     */
    function mapToColor(normalizedValue, colors, fullOutput) {
        if (!(colors &amp;&amp; colors.length) || !(normalizedValue &gt;= 0 &amp;&amp; normalizedValue <= 0="" 1="" 1))="" {="" return;="" }="" var="" value="normalizedValue" *="" (colors.length="" -="" 1);="" leftindex="Math.floor(value);" rightindex="Math.ceil(value);" leftcolor="parse(colors[leftIndex]);" rightcolor="parse(colors[rightIndex]);" dv="value" leftindex;="" color="stringify([" clampcssbyte(lerp(leftcolor[0],="" rightcolor[0],="" dv)),="" clampcssbyte(lerp(leftcolor[1],="" rightcolor[1],="" clampcssbyte(lerp(leftcolor[2],="" rightcolor[2],="" clampcssfloat(lerp(leftcolor[3],="" rightcolor[3],="" dv))="" ],="" 'rgba');="" return="" fulloutput="" ?="" color:="" color,="" leftindex:="" leftindex,="" rightindex:="" rightindex,="" value:="" :="" color;="" **="" @param="" {string}="" {number="}" h="" ~="" 360,="" ignore="" when="" null.="" s="" 1,="" l="" @return="" string="" in="" rgba="" format.="" @memberof="" module:zrender="" util="" function="" modifyhsl(color,="" h,="" s,="" l)="" if="" (color)="" !="null" &&="" (color[0]="clampCssAngle(h));" (color[1]="parseCssFloat(s));" (color[2]="parseCssFloat(l));" stringify(hsla2rgba(color),="" alpha="" modifyalpha(color,="" alpha)="" (color="" color[3]="clampCssFloat(alpha);" stringify(color,="" {array.<string="">} colors Color list.
     * @param {string} type &apos;rgba&apos;, &apos;hsva&apos;, ...
     * @return {string} Result color.
     */
    function stringify(arrColor, type) {
        var colorStr = arrColor[0] + &apos;,&apos; + arrColor[1] + &apos;,&apos; + arrColor[2];
        if (type === &apos;rgba&apos; || type === &apos;hsva&apos; || type === &apos;hsla&apos;) {
            colorStr += &apos;,&apos; + arrColor[3];
        }
        return type + &apos;(&apos; + colorStr + &apos;)&apos;;
    }
    return {
        parse: parse,
        lift: lift,
        toHex: toHex,
        fastMapToColor: fastMapToColor,
        mapToColor: mapToColor,
        modifyHSL: modifyHSL,
        modifyAlpha: modifyAlpha,
        stringify: stringify
    };
});
define(&apos;zrender/mixin/Eventful&apos;, [&apos;require&apos;], function (require) {
    var arrySlice = Array.prototype.slice;
    /**
     * &#x4E8B;&#x4EF6;&#x5206;&#x53D1;&#x5668;
     * @alias module:zrender/mixin/Eventful
     * @constructor
     */
    var Eventful = function () {
        this._$handlers = {};
    };
    Eventful.prototype = {
        constructor: Eventful,
        one: function (event, handler, context) {
            var _h = this._$handlers;
            if (!handler || !event) {
                return this;
            }
            if (!_h[event]) {
                _h[event] = [];
            }
            for (var i = 0; i &lt; _h[event].length; i++) {
                if (_h[event][i].h === handler) {
                    return this;
                }
            }
            _h[event].push({
                h: handler,
                one: true,
                ctx: context || this
            });
            return this;
        },
        on: function (event, handler, context) {
            var _h = this._$handlers;
            if (!handler || !event) {
                return this;
            }
            if (!_h[event]) {
                _h[event] = [];
            }
            for (var i = 0; i &lt; _h[event].length; i++) {
                if (_h[event][i].h === handler) {
                    return this;
                }
            }
            _h[event].push({
                h: handler,
                one: false,
                ctx: context || this
            });
            return this;
        },
        isSilent: function (event) {
            var _h = this._$handlers;
            return _h[event] &amp;&amp; _h[event].length;
        },
        off: function (event, handler) {
            var _h = this._$handlers;
            if (!event) {
                this._$handlers = {};
                return this;
            }
            if (handler) {
                if (_h[event]) {
                    var newList = [];
                    for (var i = 0, l = _h[event].length; i &lt; l; i++) {
                        if (_h[event][i][&apos;h&apos;] != handler) {
                            newList.push(_h[event][i]);
                        }
                    }
                    _h[event] = newList;
                }
                if (_h[event] &amp;&amp; _h[event].length === 0) {
                    delete _h[event];
                }
            } else {
                delete _h[event];
            }
            return this;
        },
        trigger: function (type) {
            if (this._$handlers[type]) {
                var args = arguments;
                var argLen = args.length;
                if (argLen &gt; 3) {
                    args = arrySlice.call(args, 1);
                }
                var _h = this._$handlers[type];
                var len = _h.length;
                for (var i = 0; i &lt; len;) {
                    // Optimize advise from backbone
                    switch (argLen) {
                    case 1:
                        _h[i][&apos;h&apos;].call(_h[i][&apos;ctx&apos;]);
                        break;
                    case 2:
                        _h[i][&apos;h&apos;].call(_h[i][&apos;ctx&apos;], args[1]);
                        break;
                    case 3:
                        _h[i][&apos;h&apos;].call(_h[i][&apos;ctx&apos;], args[1], args[2]);
                        break;
                    default:
                        // have more than 2 given arguments
                        _h[i][&apos;h&apos;].apply(_h[i][&apos;ctx&apos;], args);
                        break;
                    }
                    if (_h[i][&apos;one&apos;]) {
                        _h.splice(i, 1);
                        len--;
                    } else {
                        i++;
                    }
                }
            }
            return this;
        },
        triggerWithContext: function (type) {
            if (this._$handlers[type]) {
                var args = arguments;
                var argLen = args.length;
                if (argLen &gt; 4) {
                    args = arrySlice.call(args, 1, args.length - 1);
                }
                var ctx = args[args.length - 1];
                var _h = this._$handlers[type];
                var len = _h.length;
                for (var i = 0; i &lt; len;) {
                    // Optimize advise from backbone
                    switch (argLen) {
                    case 1:
                        _h[i][&apos;h&apos;].call(ctx);
                        break;
                    case 2:
                        _h[i][&apos;h&apos;].call(ctx, args[1]);
                        break;
                    case 3:
                        _h[i][&apos;h&apos;].call(ctx, args[1], args[2]);
                        break;
                    default:
                        // have more than 2 given arguments
                        _h[i][&apos;h&apos;].apply(ctx, args);
                        break;
                    }
                    if (_h[i][&apos;one&apos;]) {
                        _h.splice(i, 1);
                        len--;
                    } else {
                        i++;
                    }
                }
            }
            return this;
        }
    };
    // &#x5BF9;&#x8C61;&#x53EF;&#x4EE5;&#x901A;&#x8FC7; onxxxx &#x7ED1;&#x5B9A;&#x4E8B;&#x4EF6;
    /**
     * @event module:zrender/mixin/Eventful#onclick
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#onmouseover
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#onmouseout
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#onmousemove
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#onmousewheel
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#onmousedown
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#onmouseup
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#ondragstart
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#ondragend
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#ondragenter
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#ondragleave
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#ondragover
     * @type {Function}
     * @default null
     */
    /**
     * @event module:zrender/mixin/Eventful#ondrop
     * @type {Function}
     * @default null
     */
    return Eventful;
});
define(&apos;echarts/loading/default&apos;, [&apos;require&apos;, &apos;../util/graphic&apos;, &apos;zrender/core/util&apos;], function (require) {
    var graphic = require(&apos;../util/graphic&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var PI = Math.PI;
    /**
     * @param {module:echarts/ExtensionAPI} api
     * @param {Object} [opts]
     * @param {string} [opts.text]
     * @param {string} [opts.color]
     * @param {string} [opts.textColor]
     * @return {module:zrender/Element}
     */
    return function (api, opts) {
        opts = opts || {};
        zrUtil.defaults(opts, {
            text: &apos;loading&apos;,
            color: &apos;#c23531&apos;,
            textColor: &apos;#000&apos;,
            maskColor: &apos;rgba(255, 255, 255, 0.8)&apos;,
            zlevel: 0
        });
        var mask = new graphic.Rect({
                style: { fill: opts.maskColor },
                zlevel: opts.zlevel,
                z: 10000
            });
        var arc = new graphic.Arc({
                shape: {
                    startAngle: -PI / 2,
                    endAngle: -PI / 2 + 0.1,
                    r: 10
                },
                style: {
                    stroke: opts.color,
                    lineCap: &apos;round&apos;,
                    lineWidth: 5
                },
                zlevel: opts.zlevel,
                z: 10001
            });
        var labelRect = new graphic.Rect({
                style: {
                    fill: &apos;none&apos;,
                    text: opts.text,
                    textPosition: &apos;right&apos;,
                    textDistance: 10,
                    textFill: opts.textColor
                },
                zlevel: opts.zlevel,
                z: 10001
            });
        arc.animateShape(true).when(1000, { endAngle: PI * 3 / 2 }).start(&apos;circularInOut&apos;);
        arc.animateShape(true).when(1000, { startAngle: PI * 3 / 2 }).delay(300).start(&apos;circularInOut&apos;);
        var group = new graphic.Group();
        group.add(arc);
        group.add(labelRect);
        group.add(mask);
        // Inject resize
        group.resize = function () {
            var cx = api.getWidth() / 2;
            var cy = api.getHeight() / 2;
            arc.setShape({
                cx: cx,
                cy: cy
            });
            var r = arc.shape.r;
            labelRect.setShape({
                x: cx - r,
                y: cy - r,
                width: r * 2,
                height: r * 2
            });
            mask.setShape({
                x: 0,
                y: 0,
                width: api.getWidth(),
                height: api.getHeight()
            });
        };
        group.resize();
        return group;
    };
});
define(&apos;echarts/visual/seriesColor&apos;, [&apos;require&apos;, &apos;zrender/graphic/Gradient&apos;], function (require) {
    var Gradient = require(&apos;zrender/graphic/Gradient&apos;);
    return function (ecModel) {
        function encodeColor(seriesModel) {
            var colorAccessPath = (seriesModel.visualColorAccessPath || &apos;itemStyle.normal.color&apos;).split(&apos;.&apos;);
            var data = seriesModel.getData();
            var color = seriesModel.get(colorAccessPath) || seriesModel.getColorFromPalette(seriesModel.get(&apos;name&apos;));
            // Default color
            // FIXME Set color function or use the platte color
            data.setVisual(&apos;color&apos;, color);
            // Only visible series has each data be visual encoded
            if (!ecModel.isSeriesFiltered(seriesModel)) {
                if (typeof color === &apos;function&apos; &amp;&amp; !(color instanceof Gradient)) {
                    data.each(function (idx) {
                        data.setItemVisual(idx, &apos;color&apos;, color(seriesModel.getDataParams(idx)));
                    });
                }
                // itemStyle in each data item
                data.each(function (idx) {
                    var itemModel = data.getItemModel(idx);
                    var color = itemModel.get(colorAccessPath, true);
                    if (color != null) {
                        data.setItemVisual(idx, &apos;color&apos;, color);
                    }
                });
            }
        }
        ecModel.eachRawSeries(encodeColor);
    };
});
define(&apos;echarts/preprocessor/backwardCompat&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;./helper/compatStyle&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var compatStyle = require(&apos;./helper/compatStyle&apos;);
    function get(opt, path) {
        path = path.split(&apos;,&apos;);
        var obj = opt;
        for (var i = 0; i &lt; path.length; i++) {
            obj = obj &amp;&amp; obj[path[i]];
            if (obj == null) {
                break;
            }
        }
        return obj;
    }
    function set(opt, path, val, overwrite) {
        path = path.split(&apos;,&apos;);
        var obj = opt;
        var key;
        for (var i = 0; i &lt; path.length - 1; i++) {
            key = path[i];
            if (obj[key] == null) {
                obj[key] = {};
            }
            obj = obj[key];
        }
        if (overwrite || obj[path[i]] == null) {
            obj[path[i]] = val;
        }
    }
    function compatLayoutProperties(option) {
        each(LAYOUT_PROPERTIES, function (prop) {
            if (prop[0] in option &amp;&amp; !(prop[1] in option)) {
                option[prop[1]] = option[prop[0]];
            }
        });
    }
    var LAYOUT_PROPERTIES = [
            [
                &apos;x&apos;,
                &apos;left&apos;
            ],
            [
                &apos;y&apos;,
                &apos;top&apos;
            ],
            [
                &apos;x2&apos;,
                &apos;right&apos;
            ],
            [
                &apos;y2&apos;,
                &apos;bottom&apos;
            ]
        ];
    var COMPATITABLE_COMPONENTS = [
            &apos;grid&apos;,
            &apos;geo&apos;,
            &apos;parallel&apos;,
            &apos;legend&apos;,
            &apos;toolbox&apos;,
            &apos;title&apos;,
            &apos;visualMap&apos;,
            &apos;dataZoom&apos;,
            &apos;timeline&apos;
        ];
    var COMPATITABLE_SERIES = [
            &apos;bar&apos;,
            &apos;boxplot&apos;,
            &apos;candlestick&apos;,
            &apos;chord&apos;,
            &apos;effectScatter&apos;,
            &apos;funnel&apos;,
            &apos;gauge&apos;,
            &apos;lines&apos;,
            &apos;graph&apos;,
            &apos;heatmap&apos;,
            &apos;line&apos;,
            &apos;map&apos;,
            &apos;parallel&apos;,
            &apos;pie&apos;,
            &apos;radar&apos;,
            &apos;sankey&apos;,
            &apos;scatter&apos;,
            &apos;treemap&apos;
        ];
    var each = zrUtil.each;
    return function (option) {
        each(option.series, function (seriesOpt) {
            if (!zrUtil.isObject(seriesOpt)) {
                return;
            }
            var seriesType = seriesOpt.type;
            compatStyle(seriesOpt);
            if (seriesType === &apos;pie&apos; || seriesType === &apos;gauge&apos;) {
                if (seriesOpt.clockWise != null) {
                    seriesOpt.clockwise = seriesOpt.clockWise;
                }
            }
            if (seriesType === &apos;gauge&apos;) {
                var pointerColor = get(seriesOpt, &apos;pointer.color&apos;);
                pointerColor != null &amp;&amp; set(seriesOpt, &apos;itemStyle.normal.color&apos;, pointerColor);
            }
            for (var i = 0; i &lt; COMPATITABLE_SERIES.length; i++) {
                if (COMPATITABLE_SERIES[i] === seriesOpt.type) {
                    compatLayoutProperties(seriesOpt);
                    break;
                }
            }
        });
        // dataRange has changed to visualMap
        if (option.dataRange) {
            option.visualMap = option.dataRange;
        }
        each(COMPATITABLE_COMPONENTS, function (componentName) {
            var options = option[componentName];
            if (options) {
                if (!zrUtil.isArray(options)) {
                    options = [options];
                }
                each(options, function (option) {
                    compatLayoutProperties(option);
                });
            }
        });
    };
});
define(&apos;echarts/model/Model&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../util/clazz&apos;, &apos;./mixin/lineStyle&apos;, &apos;./mixin/areaStyle&apos;, &apos;./mixin/textStyle&apos;, &apos;./mixin/itemStyle&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var clazzUtil = require(&apos;../util/clazz&apos;);
    /**
     * @alias module:echarts/model/Model
     * @constructor
     * @param {Object} option
     * @param {module:echarts/model/Model} [parentModel]
     * @param {module:echarts/model/Global} [ecModel]
     */
    function Model(option, parentModel, ecModel) {
        /**
         * @type {module:echarts/model/Model}
         * @readOnly
         */
        this.parentModel = parentModel;
        /**
         * @type {module:echarts/model/Global}
         * @readOnly
         */
        this.ecModel = ecModel;
        /**
         * @type {Object}
         * @protected
         */
        this.option = option;    // Simple optimization
                                 // if (this.init) {
                                 //     if (arguments.length <= 4)="" {="" this.init(option,="" parentmodel,="" ecmodel,="" extraopt);="" }="" else="" this.init.apply(this,="" arguments);="" model.prototype="{" constructor:="" model,="" init:="" null,="" mergeoption:="" function="" (option)="" zrutil.merge(this.option,="" option,="" true);="" },="" get:="" (path,="" ignoreparent)="" if="" (!path)="" return="" this.option;="" (typeof="" path="==" 'string')="" var="" obj="this.option;" parentmodel="this.parentModel;" for="" (var="" i="0;" <="" path.length;="" i++)="" ignore="" empty="" (!path[i])="" continue;="" could="" be="" number="" string="" ...="" (like="" 0)="" &&="" typeof="" 'object'="" ?="" obj[path[i]]="" :="" null;="" (obj="=" null)="" break;="" null="" !ignoreparent)="" obj;="" getshallow:="" (key,="" option="this.option;" val="option" option[key];="" (val="=" val;="" getmodel:="" parentmodel)="" thisparentmodel="this.parentModel;" model="new" model(obj,="" ||="" thisparentmodel.getmodel(path),="" this.ecmodel);="" model;="" isempty:="" ()="" this.option="=" restoredata:="" clone:="" ctor="this.constructor;" new="" ctor(zrutil.clone(this.option));="" setreadonly:="" (properties)="" clazzutil.setreadonly(this,="" properties);="" };="" enable="" model.extend.="" clazzutil.enableclassextend(model);="" mixin="zrUtil.mixin;" mixin(model,="" require('.="" linestyle'));="" areastyle'));="" textstyle'));="" itemstyle'));="" });="" define('echarts="" data="" list',="" ['require',="" '..="" model',="" '.="" datadiffer',="" 'zrender="" core="" util',="" util="" model'],="" (require)="" undefined="undefined" ;="" globalobj="typeof" window="==" 'undefined'="" global="" window;="" float64array="typeof" globalobj.float64array="==" array="" globalobj.float64array;="" int32array="typeof" globalobj.int32array="==" globalobj.int32array;="" datactors="{" 'float':="" float64array,="" 'int':="" int32array,="" 'ordinal':="" array,="" 'number':="" 'time':="" datadiffer="require(&apos;./DataDiffer&apos;);" zrutil="require(&apos;zrender/core/util&apos;);" modelutil="require(&apos;../util/model&apos;);" isobject="zrUtil.isObject;" transferable_properties="[" 'stackedon',="" 'hasitemoption',="" '_namelist',="" '_idlist',="" '_rawdata'="" ];="" transferproperties="function" (a,="" b)="" zrutil.each(transferable_properties.concat(b.__wrappedmethods="" []),="" (propname)="" (b.hasownproperty(propname))="" a[propname]="b[propName];" a.__wrappedmethods="b.__wrappedMethods;" **="" *="" @constructor="" @alias="" module:echarts="" list="" @param="" {array.<string="">} dimensions
     *        Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
     * @param {module:echarts/model/Model} hostModel
     */
    var List = function (dimensions, hostModel) {
        dimensions = dimensions || [
            &apos;x&apos;,
            &apos;y&apos;
        ];
        var dimensionInfos = {};
        var dimensionNames = [];
        for (var i = 0; i &lt; dimensions.length; i++) {
            var dimensionName;
            var dimensionInfo = {};
            if (typeof dimensions[i] === &apos;string&apos;) {
                dimensionName = dimensions[i];
                dimensionInfo = {
                    name: dimensionName,
                    stackable: false,
                    type: &apos;number&apos;
                };
            } else {
                dimensionInfo = dimensions[i];
                dimensionName = dimensionInfo.name;
                dimensionInfo.type = dimensionInfo.type || &apos;number&apos;;
            }
            dimensionNames.push(dimensionName);
            dimensionInfos[dimensionName] = dimensionInfo;
        }
        /**
         * @readOnly
         * @type {Array.<string>}
         */
        this.dimensions = dimensionNames;
        /**
         * Infomation of each data dimension, like data type.
         * @type {Object}
         */
        this._dimensionInfos = dimensionInfos;
        /**
         * @type {module:echarts/model/Model}
         */
        this.hostModel = hostModel;
        /**
         * @type {module:echarts/model/Model}
         */
        this.dataType;
        /**
         * Indices stores the indices of data subset after filtered.
         * This data subset will be used in chart.
         * @type {Array.<number>}
         * @readOnly
         */
        this.indices = [];
        /**
         * Data storage
         * @type {Object.<key, typedarray|array="">}
         * @private
         */
        this._storage = {};
        /**
         * @type {Array.<string>}
         */
        this._nameList = [];
        /**
         * @type {Array.<string>}
         */
        this._idList = [];
        /**
         * Models of data option is stored sparse for optimizing memory cost
         * @type {Array.<module:echarts model="">}
         * @private
         */
        this._optionModels = [];
        /**
         * @param {module:echarts/data/List}
         */
        this.stackedOn = null;
        /**
         * Global visual properties after visual coding
         * @type {Object}
         * @private
         */
        this._visual = {};
        /**
         * Globel layout properties.
         * @type {Object}
         * @private
         */
        this._layout = {};
        /**
         * Item visual properties after visual coding
         * @type {Array.<object>}
         * @private
         */
        this._itemVisuals = [];
        /**
         * Item layout properties after layout
         * @type {Array.<object>}
         * @private
         */
        this._itemLayouts = [];
        /**
         * Graphic elemnents
         * @type {Array.<module:zrender element="">}
         * @private
         */
        this._graphicEls = [];
        /**
         * @type {Array.<array|object>}
         * @private
         */
        this._rawData;
        /**
         * @type {Object}
         * @private
         */
        this._extent;
    };
    var listProto = List.prototype;
    listProto.type = &apos;list&apos;;
    /**
     * If each data item has it&apos;s own option
     * @type {boolean}
     */
    listProto.hasItemOption = true;
    /**
     * Get dimension name
     * @param {string|number} dim
     *        Dimension can be concrete names like x, y, z, lng, lat, angle, radius
     *        Or a ordinal number. For example getDimensionInfo(0) will return &apos;x&apos; or &apos;lng&apos; or &apos;radius&apos;
     * @return {string} Concrete dim name.
     */
    listProto.getDimension = function (dim) {
        if (!isNaN(dim)) {
            dim = this.dimensions[dim] || dim;
        }
        return dim;
    };
    /**
     * Get type and stackable info of particular dimension
     * @param {string|number} dim
     *        Dimension can be concrete names like x, y, z, lng, lat, angle, radius
     *        Or a ordinal number. For example getDimensionInfo(0) will return &apos;x&apos; or &apos;lng&apos; or &apos;radius&apos;
     */
    listProto.getDimensionInfo = function (dim) {
        return zrUtil.clone(this._dimensionInfos[this.getDimension(dim)]);
    };
    /**
     * Initialize from data
     * @param {Array.<object|number|array>} data
     * @param {Array.<string>} [nameList]
     * @param {Function} [dimValueGetter] (dataItem, dimName, dataIndex, dimIndex) =&gt; number
     */
    listProto.initData = function (data, nameList, dimValueGetter) {
        data = data || [];
        if (true) {
            if (!zrUtil.isArray(data)) {
                throw new Error(&apos;Invalid data.&apos;);
            }
        }
        this._rawData = data;
        // Clear
        var storage = this._storage = {};
        var indices = this.indices = [];
        var dimensions = this.dimensions;
        var size = data.length;
        var dimensionInfoMap = this._dimensionInfos;
        var idList = [];
        var nameRepeatCount = {};
        nameList = nameList || [];
        // Init storage
        for (var i = 0; i &lt; dimensions.length; i++) {
            var dimInfo = dimensionInfoMap[dimensions[i]];
            var DataCtor = dataCtors[dimInfo.type];
            storage[dimensions[i]] = new DataCtor(size);
        }
        var self = this;
        if (!dimValueGetter) {
            self.hasItemOption = false;
        }
        // Default dim value getter
        dimValueGetter = dimValueGetter || function (dataItem, dimName, dataIndex, dimIndex) {
            var value = modelUtil.getDataItemValue(dataItem);
            // If any dataItem is like { value: 10 }
            if (modelUtil.isDataItemOption(dataItem)) {
                self.hasItemOption = true;
            }
            return modelUtil.converDataValue(value instanceof Array ? value[dimIndex] : value, dimensionInfoMap[dimName]);
        };
        for (var idx = 0; idx &lt; data.length; idx++) {
            var dataItem = data[idx];
            // Each data item is value
            // [1, 2]
            // 2
            // Bar chart, line chart which uses category axis
            // only gives the &apos;y&apos; value. &apos;x&apos; value is the indices of cateogry
            // Use a tempValue to normalize the value to be a (x, y) value
            // Store the data by dimensions
            for (var k = 0; k &lt; dimensions.length; k++) {
                var dim = dimensions[k];
                var dimStorage = storage[dim];
                // PENDING NULL is empty or zero
                dimStorage[idx] = dimValueGetter(dataItem, dim, idx, k);
            }
            indices.push(idx);
        }
        // Use the name in option and create id
        for (var i = 0; i &lt; data.length; i++) {
            if (!nameList[i]) {
                if (data[i] &amp;&amp; data[i].name != null) {
                    nameList[i] = data[i].name;
                }
            }
            var name = nameList[i] || &apos;&apos;;
            // Try using the id in option
            var id = data[i] &amp;&amp; data[i].id;
            if (!id &amp;&amp; name) {
                // Use name as id and add counter to avoid same name
                nameRepeatCount[name] = nameRepeatCount[name] || 0;
                id = name;
                if (nameRepeatCount[name] &gt; 0) {
                    id += &apos;__ec__&apos; + nameRepeatCount[name];
                }
                nameRepeatCount[name]++;
            }
            id &amp;&amp; (idList[i] = id);
        }
        this._nameList = nameList;
        this._idList = idList;
    };
    /**
     * @return {number}
     */
    listProto.count = function () {
        return this.indices.length;
    };
    /**
     * Get value. Return NaN if idx is out of range.
     * @param {string} dim Dim must be concrete name.
     * @param {number} idx
     * @param {boolean} stack
     * @return {number}
     */
    listProto.get = function (dim, idx, stack) {
        var storage = this._storage;
        var dataIndex = this.indices[idx];
        // If value not exists
        if (dataIndex == null) {
            return NaN;
        }
        var value = storage[dim] &amp;&amp; storage[dim][dataIndex];
        // FIXME ordinal data type is not stackable
        if (stack) {
            var dimensionInfo = this._dimensionInfos[dim];
            if (dimensionInfo &amp;&amp; dimensionInfo.stackable) {
                var stackedOn = this.stackedOn;
                while (stackedOn) {
                    // Get no stacked data of stacked on
                    var stackedValue = stackedOn.get(dim, idx);
                    // Considering positive stack, negative stack and empty data
                    if (value &gt;= 0 &amp;&amp; stackedValue &gt; 0 || value <= 0="" &&="" stackedvalue="" <="" 0)="" {="" value="" +="stackedValue;" }="" stackedon="stackedOn.stackedOn;" return="" value;="" };="" **="" *="" get="" for="" multi="" dimensions.="" @param="" {array.<string="">} [dimensions] If ignored, using all dimensions.
     * @param {number} idx
     * @param {boolean} stack
     * @return {number}
     */
    listProto.getValues = function (dimensions, idx, stack) {
        var values = [];
        if (!zrUtil.isArray(dimensions)) {
            stack = idx;
            idx = dimensions;
            dimensions = this.dimensions;
        }
        for (var i = 0, len = dimensions.length; i &lt; len; i++) {
            values.push(this.get(dimensions[i], idx, stack));
        }
        return values;
    };
    /**
     * If value is NaN. Inlcuding &apos;-&apos;
     * @param {string} dim
     * @param {number} idx
     * @return {number}
     */
    listProto.hasValue = function (idx) {
        var dimensions = this.dimensions;
        var dimensionInfos = this._dimensionInfos;
        for (var i = 0, len = dimensions.length; i &lt; len; i++) {
            if (dimensionInfos[dimensions[i]].type !== &apos;ordinal&apos; &amp;&amp; isNaN(this.get(dimensions[i], idx))) {
                return false;
            }
        }
        return true;
    };
    /**
     * Get extent of data in one dimension
     * @param {string} dim
     * @param {boolean} stack
     */
    listProto.getDataExtent = function (dim, stack) {
        dim = this.getDimension(dim);
        var dimData = this._storage[dim];
        var dimInfo = this.getDimensionInfo(dim);
        stack = dimInfo &amp;&amp; dimInfo.stackable &amp;&amp; stack;
        var dimExtent = (this._extent || (this._extent = {}))[dim + !!stack];
        var value;
        if (dimExtent) {
            return dimExtent;
        }
        // var dimInfo = this._dimensionInfos[dim];
        if (dimData) {
            var min = Infinity;
            var max = -Infinity;
            // var isOrdinal = dimInfo.type === &apos;ordinal&apos;;
            for (var i = 0, len = this.count(); i &lt; len; i++) {
                value = this.get(dim, i, stack);
                // FIXME
                // if (isOrdinal &amp;&amp; typeof value === &apos;string&apos;) {
                //     value = zrUtil.indexOf(dimData, value);
                // }
                value &lt; min &amp;&amp; (min = value);
                value &gt; max &amp;&amp; (max = value);
            }
            return this._extent[dim + !!stack] = [
                min,
                max
            ];
        } else {
            return [
                Infinity,
                -Infinity
            ];
        }
    };
    /**
     * Get sum of data in one dimension
     * @param {string} dim
     * @param {boolean} stack
     */
    listProto.getSum = function (dim, stack) {
        var dimData = this._storage[dim];
        var sum = 0;
        if (dimData) {
            for (var i = 0, len = this.count(); i &lt; len; i++) {
                var value = this.get(dim, i, stack);
                if (!isNaN(value)) {
                    sum += value;
                }
            }
        }
        return sum;
    };
    /**
     * Retreive the index with given value
     * @param {number} idx
     * @param {number} value
     * @return {number}
     */
    // FIXME Precision of float value
    listProto.indexOf = function (dim, value) {
        var storage = this._storage;
        var dimData = storage[dim];
        var indices = this.indices;
        if (dimData) {
            for (var i = 0, len = indices.length; i &lt; len; i++) {
                var rawIndex = indices[i];
                if (dimData[rawIndex] === value) {
                    return i;
                }
            }
        }
        return -1;
    };
    /**
     * Retreive the index with given name
     * @param {number} idx
     * @param {number} name
     * @return {number}
     */
    listProto.indexOfName = function (name) {
        var indices = this.indices;
        var nameList = this._nameList;
        for (var i = 0, len = indices.length; i &lt; len; i++) {
            var rawIndex = indices[i];
            if (nameList[rawIndex] === name) {
                return i;
            }
        }
        return -1;
    };
    /**
     * Retreive the index with given raw data index
     * @param {number} idx
     * @param {number} name
     * @return {number}
     */
    listProto.indexOfRawIndex = function (rawIndex) {
        // Indices are ascending
        var indices = this.indices;
        var left = 0;
        var right = indices.length - 1;
        while (left <= 2="" right)="" {="" var="" mid="(left" +="" |="" 0;="" if="" (indices[mid]="" <="" rawindex)="" left="mid" 1;="" }="" else=""> rawIndex) {
                right = mid - 1;
            } else {
                return mid;
            }
        }
        return -1;
    };
    /**
     * Retreive the index of nearest value
     * @param {string} dim
     * @param {number} value
     * @param {boolean} stack If given value is after stacked
     * @param {number} [maxDistance=Infinity]
     * @return {number}
     */
    listProto.indexOfNearest = function (dim, value, stack, maxDistance) {
        var storage = this._storage;
        var dimData = storage[dim];
        if (maxDistance == null) {
            maxDistance = Infinity;
        }
        var nearestIdx = -1;
        if (dimData) {
            var minDist = Number.MAX_VALUE;
            for (var i = 0, len = this.count(); i &lt; len; i++) {
                var diff = value - this.get(dim, i, stack);
                var dist = Math.abs(diff);
                if (diff <= maxdistance="" &&="" (dist="" <="" mindist="" ||="" dist="==" diff=""> 0)) {
                    minDist = dist;
                    nearestIdx = i;
                }
            }
        }
        return nearestIdx;
    };
    /**
     * Get raw data index
     * @param {number} idx
     * @return {number}
     */
    listProto.getRawIndex = function (idx) {
        var rawIdx = this.indices[idx];
        return rawIdx == null ? -1 : rawIdx;
    };
    /**
     * Get raw data item
     * @param {number} idx
     * @return {number}
     */
    listProto.getRawDataItem = function (idx) {
        return this._rawData[this.getRawIndex(idx)];
    };
    /**
     * @param {number} idx
     * @param {boolean} [notDefaultIdx=false]
     * @return {string}
     */
    listProto.getName = function (idx) {
        return this._nameList[this.indices[idx]] || &apos;&apos;;
    };
    /**
     * @param {number} idx
     * @param {boolean} [notDefaultIdx=false]
     * @return {string}
     */
    listProto.getId = function (idx) {
        return this._idList[this.indices[idx]] || this.getRawIndex(idx) + &apos;&apos;;
    };
    function normalizeDimensions(dimensions) {
        if (!zrUtil.isArray(dimensions)) {
            dimensions = [dimensions];
        }
        return dimensions;
    }
    /**
     * Data iteration
     * @param {string|Array.<string>}
     * @param {Function} cb
     * @param {boolean} [stack=false]
     * @param {*} [context=this]
     *
     * @example
     *  list.each(&apos;x&apos;, function (x, idx) {});
     *  list.each([&apos;x&apos;, &apos;y&apos;], function (x, y, idx) {});
     *  list.each(function (idx) {})
     */
    listProto.each = function (dims, cb, stack, context) {
        if (typeof dims === &apos;function&apos;) {
            context = stack;
            stack = cb;
            cb = dims;
            dims = [];
        }
        dims = zrUtil.map(normalizeDimensions(dims), this.getDimension, this);
        var value = [];
        var dimSize = dims.length;
        var indices = this.indices;
        context = context || this;
        for (var i = 0; i &lt; indices.length; i++) {
            // Simple optimization
            switch (dimSize) {
            case 0:
                cb.call(context, i);
                break;
            case 1:
                cb.call(context, this.get(dims[0], i, stack), i);
                break;
            case 2:
                cb.call(context, this.get(dims[0], i, stack), this.get(dims[1], i, stack), i);
                break;
            default:
                for (var k = 0; k &lt; dimSize; k++) {
                    value[k] = this.get(dims[k], i, stack);
                }
                // Index
                value[k] = i;
                cb.apply(context, value);
            }
        }
    };
    /**
     * Data filter
     * @param {string|Array.<string>}
     * @param {Function} cb
     * @param {boolean} [stack=false]
     * @param {*} [context=this]
     */
    listProto.filterSelf = function (dimensions, cb, stack, context) {
        if (typeof dimensions === &apos;function&apos;) {
            context = stack;
            stack = cb;
            cb = dimensions;
            dimensions = [];
        }
        dimensions = zrUtil.map(normalizeDimensions(dimensions), this.getDimension, this);
        var newIndices = [];
        var value = [];
        var dimSize = dimensions.length;
        var indices = this.indices;
        context = context || this;
        for (var i = 0; i &lt; indices.length; i++) {
            var keep;
            // Simple optimization
            if (dimSize === 1) {
                keep = cb.call(context, this.get(dimensions[0], i, stack), i);
            } else {
                for (var k = 0; k &lt; dimSize; k++) {
                    value[k] = this.get(dimensions[k], i, stack);
                }
                value[k] = i;
                keep = cb.apply(context, value);
            }
            if (keep) {
                newIndices.push(indices[i]);
            }
        }
        this.indices = newIndices;
        // Reset data extent
        this._extent = {};
        return this;
    };
    /**
     * Data mapping to a plain array
     * @param {string|Array.<string>} [dimensions]
     * @param {Function} cb
     * @param {boolean} [stack=false]
     * @param {*} [context=this]
     * @return {Array}
     */
    listProto.mapArray = function (dimensions, cb, stack, context) {
        if (typeof dimensions === &apos;function&apos;) {
            context = stack;
            stack = cb;
            cb = dimensions;
            dimensions = [];
        }
        var result = [];
        this.each(dimensions, function () {
            result.push(cb &amp;&amp; cb.apply(this, arguments));
        }, stack, context);
        return result;
    };
    function cloneListForMapAndSample(original, excludeDimensions) {
        var allDimensions = original.dimensions;
        var list = new List(zrUtil.map(allDimensions, original.getDimensionInfo, original), original.hostModel);
        // FIXME If needs stackedOn, value may already been stacked
        transferProperties(list, original);
        var storage = list._storage = {};
        var originalStorage = original._storage;
        // Init storage
        for (var i = 0; i &lt; allDimensions.length; i++) {
            var dim = allDimensions[i];
            var dimStore = originalStorage[dim];
            if (zrUtil.indexOf(excludeDimensions, dim) &gt;= 0) {
                storage[dim] = new dimStore.constructor(originalStorage[dim].length);
            } else {
                // Direct reference for other dimensions
                storage[dim] = originalStorage[dim];
            }
        }
        return list;
    }
    /**
     * Data mapping to a new List with given dimensions
     * @param {string|Array.<string>} dimensions
     * @param {Function} cb
     * @param {boolean} [stack=false]
     * @param {*} [context=this]
     * @return {Array}
     */
    listProto.map = function (dimensions, cb, stack, context) {
        dimensions = zrUtil.map(normalizeDimensions(dimensions), this.getDimension, this);
        var list = cloneListForMapAndSample(this, dimensions);
        // Following properties are all immutable.
        // So we can reference to the same value
        var indices = list.indices = this.indices;
        var storage = list._storage;
        var tmpRetValue = [];
        this.each(dimensions, function () {
            var idx = arguments[arguments.length - 1];
            var retValue = cb &amp;&amp; cb.apply(this, arguments);
            if (retValue != null) {
                // a number
                if (typeof retValue === &apos;number&apos;) {
                    tmpRetValue[0] = retValue;
                    retValue = tmpRetValue;
                }
                for (var i = 0; i &lt; retValue.length; i++) {
                    var dim = dimensions[i];
                    var dimStore = storage[dim];
                    var rawIdx = indices[idx];
                    if (dimStore) {
                        dimStore[rawIdx] = retValue[i];
                    }
                }
            }
        }, stack, context);
        return list;
    };
    /**
     * Large data down sampling on given dimension
     * @param {string} dimension
     * @param {number} rate
     * @param {Function} sampleValue
     * @param {Function} sampleIndex Sample index for name and id
     */
    listProto.downSample = function (dimension, rate, sampleValue, sampleIndex) {
        var list = cloneListForMapAndSample(this, [dimension]);
        var storage = this._storage;
        var targetStorage = list._storage;
        var originalIndices = this.indices;
        var indices = list.indices = [];
        var frameValues = [];
        var frameIndices = [];
        var frameSize = Math.floor(1 / rate);
        var dimStore = targetStorage[dimension];
        var len = this.count();
        // Copy data from original data
        for (var i = 0; i &lt; storage[dimension].length; i++) {
            targetStorage[dimension][i] = storage[dimension][i];
        }
        for (var i = 0; i &lt; len; i += frameSize) {
            // Last frame
            if (frameSize &gt; len - i) {
                frameSize = len - i;
                frameValues.length = frameSize;
            }
            for (var k = 0; k &lt; frameSize; k++) {
                var idx = originalIndices[i + k];
                frameValues[k] = dimStore[idx];
                frameIndices[k] = idx;
            }
            var value = sampleValue(frameValues);
            var idx = frameIndices[sampleIndex(frameValues, value) || 0];
            // Only write value on the filtered data
            dimStore[idx] = value;
            indices.push(idx);
        }
        return list;
    };
    /**
     * Get model of one data item.
     *
     * @param {number} idx
     */
    // FIXME Model proxy ?
    listProto.getItemModel = function (idx) {
        var hostModel = this.hostModel;
        idx = this.indices[idx];
        return new Model(this._rawData[idx], hostModel, hostModel &amp;&amp; hostModel.ecModel);
    };
    /**
     * Create a data differ
     * @param {module:echarts/data/List} otherList
     * @return {module:echarts/data/DataDiffer}
     */
    listProto.diff = function (otherList) {
        var idList = this._idList;
        var otherIdList = otherList &amp;&amp; otherList._idList;
        return new DataDiffer(otherList ? otherList.indices : [], this.indices, function (idx) {
            return otherIdList[idx] || idx + &apos;&apos;;
        }, function (idx) {
            return idList[idx] || idx + &apos;&apos;;
        });
    };
    /**
     * Get visual property.
     * @param {string} key
     */
    listProto.getVisual = function (key) {
        var visual = this._visual;
        return visual &amp;&amp; visual[key];
    };
    /**
     * Set visual property
     * @param {string|Object} key
     * @param {*} [value]
     *
     * @example
     *  setVisual(&apos;color&apos;, color);
     *  setVisual({
     *      &apos;color&apos;: color
     *  });
     */
    listProto.setVisual = function (key, val) {
        if (isObject(key)) {
            for (var name in key) {
                if (key.hasOwnProperty(name)) {
                    this.setVisual(name, key[name]);
                }
            }
            return;
        }
        this._visual = this._visual || {};
        this._visual[key] = val;
    };
    /**
     * Set layout property.
     * @param {string} key
     * @param {*} [val]
     */
    listProto.setLayout = function (key, val) {
        if (isObject(key)) {
            for (var name in key) {
                if (key.hasOwnProperty(name)) {
                    this.setLayout(name, key[name]);
                }
            }
            return;
        }
        this._layout[key] = val;
    };
    /**
     * Get layout property.
     * @param  {string} key.
     * @return {*}
     */
    listProto.getLayout = function (key) {
        return this._layout[key];
    };
    /**
     * Get layout of single data item
     * @param {number} idx
     */
    listProto.getItemLayout = function (idx) {
        return this._itemLayouts[idx];
    };
    /**
     * Set layout of single data item
     * @param {number} idx
     * @param {Object} layout
     * @param {boolean=} [merge=false]
     */
    listProto.setItemLayout = function (idx, layout, merge) {
        this._itemLayouts[idx] = merge ? zrUtil.extend(this._itemLayouts[idx] || {}, layout) : layout;
    };
    /**
     * Clear all layout of single data item
     */
    listProto.clearItemLayouts = function () {
        this._itemLayouts.length = 0;
    };
    /**
     * Get visual property of single data item
     * @param {number} idx
     * @param {string} key
     * @param {boolean} ignoreParent
     */
    listProto.getItemVisual = function (idx, key, ignoreParent) {
        var itemVisual = this._itemVisuals[idx];
        var val = itemVisual &amp;&amp; itemVisual[key];
        if (val == null &amp;&amp; !ignoreParent) {
            // Use global visual property
            return this.getVisual(key);
        }
        return val;
    };
    /**
     * Set visual property of single data item
     *
     * @param {number} idx
     * @param {string|Object} key
     * @param {*} [value]
     *
     * @example
     *  setItemVisual(0, &apos;color&apos;, color);
     *  setItemVisual(0, {
     *      &apos;color&apos;: color
     *  });
     */
    listProto.setItemVisual = function (idx, key, value) {
        var itemVisual = this._itemVisuals[idx] || {};
        this._itemVisuals[idx] = itemVisual;
        if (isObject(key)) {
            for (var name in key) {
                if (key.hasOwnProperty(name)) {
                    itemVisual[name] = key[name];
                }
            }
            return;
        }
        itemVisual[key] = value;
    };
    /**
     * Clear itemVisuals and list visual.
     */
    listProto.clearAllVisual = function () {
        this._visual = {};
        this._itemVisuals = [];
    };
    var setItemDataAndSeriesIndex = function (child) {
        child.seriesIndex = this.seriesIndex;
        child.dataIndex = this.dataIndex;
        child.dataType = this.dataType;
    };
    /**
     * Set graphic element relative to data. It can be set as null
     * @param {number} idx
     * @param {module:zrender/Element} [el]
     */
    listProto.setItemGraphicEl = function (idx, el) {
        var hostModel = this.hostModel;
        if (el) {
            // Add data index and series index for indexing the data by element
            // Useful in tooltip
            el.dataIndex = idx;
            el.dataType = this.dataType;
            el.seriesIndex = hostModel &amp;&amp; hostModel.seriesIndex;
            if (el.type === &apos;group&apos;) {
                el.traverse(setItemDataAndSeriesIndex, el);
            }
        }
        this._graphicEls[idx] = el;
    };
    /**
     * @param {number} idx
     * @return {module:zrender/Element}
     */
    listProto.getItemGraphicEl = function (idx) {
        return this._graphicEls[idx];
    };
    /**
     * @param {Function} cb
     * @param {*} context
     */
    listProto.eachItemGraphicEl = function (cb, context) {
        zrUtil.each(this._graphicEls, function (el, idx) {
            if (el) {
                cb &amp;&amp; cb.call(context, el, idx);
            }
        });
    };
    /**
     * Shallow clone a new list except visual and layout properties, and graph elements.
     * New list only change the indices.
     */
    listProto.cloneShallow = function () {
        var dimensionInfoList = zrUtil.map(this.dimensions, this.getDimensionInfo, this);
        var list = new List(dimensionInfoList, this.hostModel);
        // FIXME
        list._storage = this._storage;
        transferProperties(list, this);
        // Clone will not change the data extent and indices
        list.indices = this.indices.slice();
        if (this._extent) {
            list._extent = zrUtil.extend({}, this._extent);
        }
        return list;
    };
    /**
     * Wrap some method to add more feature
     * @param {string} methodName
     * @param {Function} injectFunction
     */
    listProto.wrapMethod = function (methodName, injectFunction) {
        var originalMethod = this[methodName];
        if (typeof originalMethod !== &apos;function&apos;) {
            return;
        }
        this.__wrappedMethods = this.__wrappedMethods || [];
        this.__wrappedMethods.push(methodName);
        this[methodName] = function () {
            var res = originalMethod.apply(this, arguments);
            return injectFunction.apply(this, [res].concat(zrUtil.slice(arguments)));
        };
    };
    // Methods that create a new list based on this list should be listed here.
    // Notice that those method should `RETURN` the new list.
    listProto.TRANSFERABLE_METHODS = [
        &apos;cloneShallow&apos;,
        &apos;downSample&apos;,
        &apos;map&apos;
    ];
    // Methods that change indices of this list should be listed here.
    listProto.CHANGABLE_METHODS = [&apos;filterSelf&apos;];
    return List;
});
define(&apos;echarts/util/number&apos;, [&apos;require&apos;], function (require) {
    var number = {};
    var RADIAN_EPSILON = 0.0001;
    function _trim(str) {
        return str.replace(/^\s+/, &apos;&apos;).replace(/\s+$/, &apos;&apos;);
    }
    /**
     * Linear mapping a value from domain to range
     * @memberOf module:echarts/util/number
     * @param  {(number|Array.<number>)} val
     * @param  {Array.<number>} domain Domain extent domain[0] can be bigger than domain[1]
     * @param  {Array.<number>} range  Range extent range[0] can be bigger than range[1]
     * @param  {boolean} clamp
     * @return {(number|Array.<number>}
     */
    number.linearMap = function (val, domain, range, clamp) {
        var subDomain = domain[1] - domain[0];
        var subRange = range[1] - range[0];
        if (subDomain === 0) {
            return subRange === 0 ? range[0] : (range[0] + range[1]) / 2;
        }
        // Avoid accuracy problem in edge, such as
        // 146.39 - 62.83 === 83.55999999999999.
        // See echarts/test/ut/spec/util/number.js#linearMap#accuracyError
        // It is a little verbose for efficiency considering this method
        // is a hotspot.
        if (clamp) {
            if (subDomain &gt; 0) {
                if (val <= domain[0])="" {="" return="" range[0];="" }="" else="" if="" (val="">= domain[1]) {
                    return range[1];
                }
            } else {
                if (val &gt;= domain[0]) {
                    return range[0];
                } else if (val <= 1="" 100="" domain[1])="" {="" return="" range[1];="" }="" else="" if="" (val="==" domain[0])="" range[0];="" -="" subdomain="" *="" subrange="" +="" };="" **="" convert="" a="" percent="" string="" to="" absolute="" number.="" returns="" nan="" is="" not="" valid="" or="" number="" @memberof="" module:echarts="" util="" @param="" {string|number}="" {number}="" all="" @return="" number.parsepercent="function" (percent,="" all)="" switch="" (percent)="" case="" 'center':="" 'middle':="" ;="" break;="" 'left':="" 'top':="" 'right':="" 'bottom':="" (typeof="" 'string')="" (_trim(percent).match(="" %$="" ))="" parsefloat(percent)="" all;="" parsefloat(percent);="" null="" ?="" :="" +percent;="" fix="" rounding="" error="" of="" float="" numbers="" x="" number.round="function" (x)="" pending="" +(+x).tofixed(10);="" number.asc="function" (arr)="" arr.sort(function="" (a,="" b)="" b;="" });="" arr;="" get="" precision="" val="" number.getprecision="function" (val)="" (isnan(val))="" 0;="" it="" much="" faster="" than="" methods="" converting="" as="" follows="" var="" tmp="val.toString();" tmp.length="" tmp.indexof('.');="" especially="" when="" low="" e="1;" count="0;" while="" (math.round(val="" e)="" !="=" val)="" count++;="" count;="" {array.<number="">} dataExtent
     * @param {Array.<number>} pixelExtent
     * @return {number}  precision
     */
    number.getPixelPrecision = function (dataExtent, pixelExtent) {
        var log = Math.log;
        var LN10 = Math.LN10;
        var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10);
        var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10);
        return Math.max(-dataQuantity + sizeQuantity, 0);
    };
    // Number.MAX_SAFE_INTEGER, ie do not support.
    number.MAX_SAFE_INTEGER = 9007199254740991;
    /**
     * To 0 - 2 * PI, considering negative radian.
     * @param {number} radian
     * @return {number}
     */
    number.remRadian = function (radian) {
        var pi2 = Math.PI * 2;
        return (radian % pi2 + pi2) % pi2;
    };
    /**
     * @param {type} radian
     * @return {boolean}
     */
    number.isRadianAroundZero = function (val) {
        return val &gt; -RADIAN_EPSILON &amp;&amp; val &lt; RADIAN_EPSILON;
    };
    /**
     * @param {string|Date|number} value
     * @return {number} timestamp
     */
    number.parseDate = function (value) {
        return value instanceof Date ? value : new Date(typeof value === &apos;string&apos; ? new Date(value.replace(/-/g, &apos;/&apos;)) - new Date(&apos;1970/01/01&apos;) : Math.round(value));
    };
    /**
     * Quantity of a number. e.g. 0.1, 1, 10, 100
     * @param  {number} val
     * @return {number}
     */
    number.quantity = function (val) {
        return Math.pow(10, Math.floor(Math.log(val) / Math.LN10));
    };
    // &quot;Nice Numbers for Graph Labels&quot; of Graphic Gems
    /**
     * find a &#x201C;nice&#x201D; number approximately equal to x. Round the number if round = true, take ceiling if round = false
     * The primary observation is that the &#x201C;nicest&#x201D; numbers in decimal are 1, 2, and 5, and all power-of-ten multiples of these numbers.
     * @param  {number} val
     * @param  {boolean} round
     * @return {number}
     */
    number.nice = function (val, round) {
        var exp10 = number.quantity(val);
        var f = val / exp10;
        // between 1 and 10
        var nf;
        if (round) {
            if (f &lt; 1.5) {
                nf = 1;
            } else if (f &lt; 2.5) {
                nf = 2;
            } else if (f &lt; 4) {
                nf = 3;
            } else if (f &lt; 7) {
                nf = 5;
            } else {
                nf = 10;
            }
        } else {
            if (f &lt; 1) {
                nf = 1;
            } else if (f &lt; 2) {
                nf = 2;
            } else if (f &lt; 3) {
                nf = 3;
            } else if (f &lt; 5) {
                nf = 5;
            } else {
                nf = 10;
            }
        }
        return nf * exp10;
    };
    return number;
});
define(&apos;zrender/core/vector&apos;, [], function () {
    var ArrayCtor = typeof Float32Array === &apos;undefined&apos; ? Array : Float32Array;
    /**
     * @typedef {Float32Array|Array.<number>} Vector2
     */
    /**
     * &#x4E8C;&#x7EF4;&#x5411;&#x91CF;&#x7C7B;
     * @exports zrender/tool/vector
     */
    var vector = {
            create: function (x, y) {
                var out = new ArrayCtor(2);
                if (x == null) {
                    x = 0;
                }
                if (y == null) {
                    y = 0;
                }
                out[0] = x;
                out[1] = y;
                return out;
            },
            copy: function (out, v) {
                out[0] = v[0];
                out[1] = v[1];
                return out;
            },
            clone: function (v) {
                var out = new ArrayCtor(2);
                out[0] = v[0];
                out[1] = v[1];
                return out;
            },
            set: function (out, a, b) {
                out[0] = a;
                out[1] = b;
                return out;
            },
            add: function (out, v1, v2) {
                out[0] = v1[0] + v2[0];
                out[1] = v1[1] + v2[1];
                return out;
            },
            scaleAndAdd: function (out, v1, v2, a) {
                out[0] = v1[0] + v2[0] * a;
                out[1] = v1[1] + v2[1] * a;
                return out;
            },
            sub: function (out, v1, v2) {
                out[0] = v1[0] - v2[0];
                out[1] = v1[1] - v2[1];
                return out;
            },
            len: function (v) {
                return Math.sqrt(this.lenSquare(v));
            },
            lenSquare: function (v) {
                return v[0] * v[0] + v[1] * v[1];
            },
            mul: function (out, v1, v2) {
                out[0] = v1[0] * v2[0];
                out[1] = v1[1] * v2[1];
                return out;
            },
            div: function (out, v1, v2) {
                out[0] = v1[0] / v2[0];
                out[1] = v1[1] / v2[1];
                return out;
            },
            dot: function (v1, v2) {
                return v1[0] * v2[0] + v1[1] * v2[1];
            },
            scale: function (out, v, s) {
                out[0] = v[0] * s;
                out[1] = v[1] * s;
                return out;
            },
            normalize: function (out, v) {
                var d = vector.len(v);
                if (d === 0) {
                    out[0] = 0;
                    out[1] = 0;
                } else {
                    out[0] = v[0] / d;
                    out[1] = v[1] / d;
                }
                return out;
            },
            distance: function (v1, v2) {
                return Math.sqrt((v1[0] - v2[0]) * (v1[0] - v2[0]) + (v1[1] - v2[1]) * (v1[1] - v2[1]));
            },
            distanceSquare: function (v1, v2) {
                return (v1[0] - v2[0]) * (v1[0] - v2[0]) + (v1[1] - v2[1]) * (v1[1] - v2[1]);
            },
            negate: function (out, v) {
                out[0] = -v[0];
                out[1] = -v[1];
                return out;
            },
            lerp: function (out, v1, v2, t) {
                out[0] = v1[0] + t * (v2[0] - v1[0]);
                out[1] = v1[1] + t * (v2[1] - v1[1]);
                return out;
            },
            applyTransform: function (out, v, m) {
                var x = v[0];
                var y = v[1];
                out[0] = m[0] * x + m[2] * y + m[4];
                out[1] = m[1] * x + m[3] * y + m[5];
                return out;
            },
            min: function (out, v1, v2) {
                out[0] = Math.min(v1[0], v2[0]);
                out[1] = Math.min(v1[1], v2[1]);
                return out;
            },
            max: function (out, v1, v2) {
                out[0] = Math.max(v1[0], v2[0]);
                out[1] = Math.max(v1[1], v2[1]);
                return out;
            }
        };
    vector.length = vector.len;
    vector.lengthSquare = vector.lenSquare;
    vector.dist = vector.distance;
    vector.distSquare = vector.distanceSquare;
    return vector;
});
define(&apos;zrender/core/timsort&apos;, [], function () {
    var DEFAULT_MIN_MERGE = 32;
    var DEFAULT_MIN_GALLOPING = 7;
    var DEFAULT_TMP_STORAGE_LENGTH = 256;
    function minRunLength(n) {
        var r = 0;
        while (n &gt;= DEFAULT_MIN_MERGE) {
            r |= n &amp; 1;
            n &gt;&gt;= 1;
        }
        return n + r;
    }
    function makeAscendingRun(array, lo, hi, compare) {
        var runHi = lo + 1;
        if (runHi === hi) {
            return 1;
        }
        if (compare(array[runHi++], array[lo]) &lt; 0) {
            while (runHi &lt; hi &amp;&amp; compare(array[runHi], array[runHi - 1]) &lt; 0) {
                runHi++;
            }
            reverseRun(array, lo, runHi);
        } else {
            while (runHi &lt; hi &amp;&amp; compare(array[runHi], array[runHi - 1]) &gt;= 0) {
                runHi++;
            }
        }
        return runHi - lo;
    }
    function reverseRun(array, lo, hi) {
        hi--;
        while (lo &lt; hi) {
            var t = array[lo];
            array[lo++] = array[hi];
            array[hi--] = t;
        }
    }
    function binaryInsertionSort(array, lo, hi, start, compare) {
        if (start === lo) {
            start++;
        }
        for (; start &lt; hi; start++) {
            var pivot = array[start];
            var left = lo;
            var right = start;
            var mid;
            while (left &lt; right) {
                mid = left + right &gt;&gt;&gt; 1;
                if (compare(pivot, array[mid]) &lt; 0) {
                    right = mid;
                } else {
                    left = mid + 1;
                }
            }
            var n = start - left;
            switch (n) {
            case 3:
                array[left + 3] = array[left + 2];
            case 2:
                array[left + 2] = array[left + 1];
            case 1:
                array[left + 1] = array[left];
                break;
            default:
                while (n &gt; 0) {
                    array[left + n] = array[left + n - 1];
                    n--;
                }
            }
            array[left] = pivot;
        }
    }
    function gallopLeft(value, array, start, length, hint, compare) {
        var lastOffset = 0;
        var maxOffset = 0;
        var offset = 1;
        if (compare(value, array[start + hint]) &gt; 0) {
            maxOffset = length - hint;
            while (offset &lt; maxOffset &amp;&amp; compare(value, array[start + hint + offset]) &gt; 0) {
                lastOffset = offset;
                offset = (offset &lt;&lt; 1) + 1;
                if (offset <= 0)="" {="" offset="maxOffset;" }="" if="" (offset=""> maxOffset) {
                offset = maxOffset;
            }
            lastOffset += hint;
            offset += hint;
        } else {
            maxOffset = hint + 1;
            while (offset &lt; maxOffset &amp;&amp; compare(value, array[start + hint - offset]) <= 0)="" {="" lastoffset="offset;" offset="(offset" <<="" 1)="" +="" 1;="" if="" (offset="" <="0)" }=""> maxOffset) {
                offset = maxOffset;
            }
            var tmp = lastOffset;
            lastOffset = hint - offset;
            offset = hint - tmp;
        }
        lastOffset++;
        while (lastOffset &lt; offset) {
            var m = lastOffset + (offset - lastOffset &gt;&gt;&gt; 1);
            if (compare(value, array[start + m]) &gt; 0) {
                lastOffset = m + 1;
            } else {
                offset = m;
            }
        }
        return offset;
    }
    function gallopRight(value, array, start, length, hint, compare) {
        var lastOffset = 0;
        var maxOffset = 0;
        var offset = 1;
        if (compare(value, array[start + hint]) &lt; 0) {
            maxOffset = hint + 1;
            while (offset &lt; maxOffset &amp;&amp; compare(value, array[start + hint - offset]) &lt; 0) {
                lastOffset = offset;
                offset = (offset &lt;&lt; 1) + 1;
                if (offset <= 0)="" {="" offset="maxOffset;" }="" if="" (offset=""> maxOffset) {
                offset = maxOffset;
            }
            var tmp = lastOffset;
            lastOffset = hint - offset;
            offset = hint - tmp;
        } else {
            maxOffset = length - hint;
            while (offset &lt; maxOffset &amp;&amp; compare(value, array[start + hint + offset]) &gt;= 0) {
                lastOffset = offset;
                offset = (offset &lt;&lt; 1) + 1;
                if (offset <= 0)="" {="" offset="maxOffset;" }="" if="" (offset=""> maxOffset) {
                offset = maxOffset;
            }
            lastOffset += hint;
            offset += hint;
        }
        lastOffset++;
        while (lastOffset &lt; offset) {
            var m = lastOffset + (offset - lastOffset &gt;&gt;&gt; 1);
            if (compare(value, array[start + m]) &lt; 0) {
                offset = m;
            } else {
                lastOffset = m + 1;
            }
        }
        return offset;
    }
    function TimSort(array, compare) {
        var minGallop = DEFAULT_MIN_GALLOPING;
        var length = 0;
        var tmpStorageLength = DEFAULT_TMP_STORAGE_LENGTH;
        var stackLength = 0;
        var runStart;
        var runLength;
        var stackSize = 0;
        length = array.length;
        if (length &lt; 2 * DEFAULT_TMP_STORAGE_LENGTH) {
            tmpStorageLength = length &gt;&gt;&gt; 1;
        }
        var tmp = [];
        stackLength = length &lt; 120 ? 5 : length &lt; 1542 ? 10 : length &lt; 119151 ? 19 : 40;
        runStart = [];
        runLength = [];
        function pushRun(_runStart, _runLength) {
            runStart[stackSize] = _runStart;
            runLength[stackSize] = _runLength;
            stackSize += 1;
        }
        function mergeRuns() {
            while (stackSize &gt; 1) {
                var n = stackSize - 2;
                if (n &gt;= 1 &amp;&amp; runLength[n - 1] <= runlength[n]="" +="" runlength[n="" 1]="" ||="" n="">= 2 &amp;&amp; runLength[n - 2] <= runlength[n]="" +="" runlength[n="" -="" 1])="" {="" if="" (runlength[n="" 1]="" <="" n--;="" }="" else="" (runlength[n]=""> runLength[n + 1]) {
                    break;
                }
                mergeAt(n);
            }
        }
        function forceMergeRuns() {
            while (stackSize &gt; 1) {
                var n = stackSize - 2;
                if (n &gt; 0 &amp;&amp; runLength[n - 1] &lt; runLength[n + 1]) {
                    n--;
                }
                mergeAt(n);
            }
        }
        function mergeAt(i) {
            var start1 = runStart[i];
            var length1 = runLength[i];
            var start2 = runStart[i + 1];
            var length2 = runLength[i + 1];
            runLength[i] = length1 + length2;
            if (i === stackSize - 3) {
                runStart[i + 1] = runStart[i + 2];
                runLength[i + 1] = runLength[i + 2];
            }
            stackSize--;
            var k = gallopRight(array[start2], array, start1, length1, 0, compare);
            start1 += k;
            length1 -= k;
            if (length1 === 0) {
                return;
            }
            length2 = gallopLeft(array[start1 + length1 - 1], array, start2, length2, length2 - 1, compare);
            if (length2 === 0) {
                return;
            }
            if (length1 <= length2)="" {="" mergelow(start1,="" length1,="" start2,="" length2);="" }="" else="" mergehigh(start1,="" function="" var="" i="0;" for="" (i="0;" <="" length1;="" i++)="" tmp[i]="array[start1" +="" i];="" cursor1="0;" cursor2="start2;" dest="start1;" array[dest++]="array[cursor2++];" if="" (--length2="==" 0)="" array[dest="" i]="tmp[cursor1" return;="" (length1="==" 1)="" length2;="" length2]="tmp[cursor1];" _mingallop="minGallop;" count1,="" count2,="" exit;="" while="" (1)="" count1="0;" count2="0;" exit="false;" do="" (compare(array[cursor2],="" tmp[cursor1])="" count2++;="" break;="" count1++;="" (--length1="==" ((count1="" |="" count2)="" _mingallop);="" (exit)="" tmp,="" cursor1,="" 0,="" compare);="" (count1="" !="=" count1;="" length1="" -="count1;" array,="" cursor2,="" length2,="" (count2="" count2;="" length2="" (length2="==" _mingallop--;="">= DEFAULT_MIN_GALLOPING || count2 &gt;= DEFAULT_MIN_GALLOPING);
                if (exit) {
                    break;
                }
                if (_minGallop &lt; 0) {
                    _minGallop = 0;
                }
                _minGallop += 2;
            }
            minGallop = _minGallop;
            minGallop &lt; 1 &amp;&amp; (minGallop = 1);
            if (length1 === 1) {
                for (i = 0; i &lt; length2; i++) {
                    array[dest + i] = array[cursor2 + i];
                }
                array[dest + length2] = tmp[cursor1];
            } else if (length1 === 0) {
                throw new Error();    // throw new Error(&apos;mergeLow preconditions were not respected&apos;);
            } else {
                for (i = 0; i &lt; length1; i++) {
                    array[dest + i] = tmp[cursor1 + i];
                }
            }
        }
        function mergeHigh(start1, length1, start2, length2) {
            var i = 0;
            for (i = 0; i &lt; length2; i++) {
                tmp[i] = array[start2 + i];
            }
            var cursor1 = start1 + length1 - 1;
            var cursor2 = length2 - 1;
            var dest = start2 + length2 - 1;
            var customCursor = 0;
            var customDest = 0;
            array[dest--] = array[cursor1--];
            if (--length1 === 0) {
                customCursor = dest - (length2 - 1);
                for (i = 0; i &lt; length2; i++) {
                    array[customCursor + i] = tmp[i];
                }
                return;
            }
            if (length2 === 1) {
                dest -= length1;
                cursor1 -= length1;
                customDest = dest + 1;
                customCursor = cursor1 + 1;
                for (i = length1 - 1; i &gt;= 0; i--) {
                    array[customDest + i] = array[customCursor + i];
                }
                array[dest] = tmp[cursor2];
                return;
            }
            var _minGallop = minGallop;
            while (true) {
                var count1 = 0;
                var count2 = 0;
                var exit = false;
                do {
                    if (compare(tmp[cursor2], array[cursor1]) &lt; 0) {
                        array[dest--] = array[cursor1--];
                        count1++;
                        count2 = 0;
                        if (--length1 === 0) {
                            exit = true;
                            break;
                        }
                    } else {
                        array[dest--] = tmp[cursor2--];
                        count2++;
                        count1 = 0;
                        if (--length2 === 1) {
                            exit = true;
                            break;
                        }
                    }
                } while ((count1 | count2) &lt; _minGallop);
                if (exit) {
                    break;
                }
                do {
                    count1 = length1 - gallopRight(tmp[cursor2], array, start1, length1, length1 - 1, compare);
                    if (count1 !== 0) {
                        dest -= count1;
                        cursor1 -= count1;
                        length1 -= count1;
                        customDest = dest + 1;
                        customCursor = cursor1 + 1;
                        for (i = count1 - 1; i &gt;= 0; i--) {
                            array[customDest + i] = array[customCursor + i];
                        }
                        if (length1 === 0) {
                            exit = true;
                            break;
                        }
                    }
                    array[dest--] = tmp[cursor2--];
                    if (--length2 === 1) {
                        exit = true;
                        break;
                    }
                    count2 = length2 - gallopLeft(array[cursor1], tmp, 0, length2, length2 - 1, compare);
                    if (count2 !== 0) {
                        dest -= count2;
                        cursor2 -= count2;
                        length2 -= count2;
                        customDest = dest + 1;
                        customCursor = cursor2 + 1;
                        for (i = 0; i &lt; count2; i++) {
                            array[customDest + i] = tmp[customCursor + i];
                        }
                        if (length2 <= 1)="" {="" exit="true;" break;="" }="" array[dest--]="array[cursor1--];" if="" (--length1="==" 0)="" _mingallop--;="" while="" (count1="">= DEFAULT_MIN_GALLOPING || count2 &gt;= DEFAULT_MIN_GALLOPING);
                if (exit) {
                    break;
                }
                if (_minGallop &lt; 0) {
                    _minGallop = 0;
                }
                _minGallop += 2;
            }
            minGallop = _minGallop;
            if (minGallop &lt; 1) {
                minGallop = 1;
            }
            if (length2 === 1) {
                dest -= length1;
                cursor1 -= length1;
                customDest = dest + 1;
                customCursor = cursor1 + 1;
                for (i = length1 - 1; i &gt;= 0; i--) {
                    array[customDest + i] = array[customCursor + i];
                }
                array[dest] = tmp[cursor2];
            } else if (length2 === 0) {
                throw new Error();    // throw new Error(&apos;mergeHigh preconditions were not respected&apos;);
            } else {
                customCursor = dest - (length2 - 1);
                for (i = 0; i &lt; length2; i++) {
                    array[customCursor + i] = tmp[i];
                }
            }
        }
        this.mergeRuns = mergeRuns;
        this.forceMergeRuns = forceMergeRuns;
        this.pushRun = pushRun;
    }
    function sort(array, compare, lo, hi) {
        if (!lo) {
            lo = 0;
        }
        if (!hi) {
            hi = array.length;
        }
        var remaining = hi - lo;
        if (remaining &lt; 2) {
            return;
        }
        var runLength = 0;
        if (remaining &lt; DEFAULT_MIN_MERGE) {
            runLength = makeAscendingRun(array, lo, hi, compare);
            binaryInsertionSort(array, lo, hi, lo + runLength, compare);
            return;
        }
        var ts = new TimSort(array, compare);
        var minRun = minRunLength(remaining);
        do {
            runLength = makeAscendingRun(array, lo, hi, compare);
            if (runLength &lt; minRun) {
                var force = remaining;
                if (force &gt; minRun) {
                    force = minRun;
                }
                binaryInsertionSort(array, lo, lo + force, lo + runLength, compare);
                runLength = force;
            }
            ts.pushRun(lo, runLength);
            ts.mergeRuns();
            remaining -= runLength;
            lo += runLength;
        } while (remaining !== 0);
        ts.forceMergeRuns();
    }
    return sort;
});
define(&apos;zrender/core/matrix&apos;, [], function () {
    var ArrayCtor = typeof Float32Array === &apos;undefined&apos; ? Array : Float32Array;
    /**
     * 3x2&#x77E9;&#x9635;&#x64CD;&#x4F5C;&#x7C7B;
     * @exports zrender/tool/matrix
     */
    var matrix = {
            create: function () {
                var out = new ArrayCtor(6);
                matrix.identity(out);
                return out;
            },
            identity: function (out) {
                out[0] = 1;
                out[1] = 0;
                out[2] = 0;
                out[3] = 1;
                out[4] = 0;
                out[5] = 0;
                return out;
            },
            copy: function (out, m) {
                out[0] = m[0];
                out[1] = m[1];
                out[2] = m[2];
                out[3] = m[3];
                out[4] = m[4];
                out[5] = m[5];
                return out;
            },
            mul: function (out, m1, m2) {
                // Consider matrix.mul(m, m2, m);
                // where out is the same as m2.
                // So use temp variable to escape error.
                var out0 = m1[0] * m2[0] + m1[2] * m2[1];
                var out1 = m1[1] * m2[0] + m1[3] * m2[1];
                var out2 = m1[0] * m2[2] + m1[2] * m2[3];
                var out3 = m1[1] * m2[2] + m1[3] * m2[3];
                var out4 = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
                var out5 = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
                out[0] = out0;
                out[1] = out1;
                out[2] = out2;
                out[3] = out3;
                out[4] = out4;
                out[5] = out5;
                return out;
            },
            translate: function (out, a, v) {
                out[0] = a[0];
                out[1] = a[1];
                out[2] = a[2];
                out[3] = a[3];
                out[4] = a[4] + v[0];
                out[5] = a[5] + v[1];
                return out;
            },
            rotate: function (out, a, rad) {
                var aa = a[0];
                var ac = a[2];
                var atx = a[4];
                var ab = a[1];
                var ad = a[3];
                var aty = a[5];
                var st = Math.sin(rad);
                var ct = Math.cos(rad);
                out[0] = aa * ct + ab * st;
                out[1] = -aa * st + ab * ct;
                out[2] = ac * ct + ad * st;
                out[3] = -ac * st + ct * ad;
                out[4] = ct * atx + st * aty;
                out[5] = ct * aty - st * atx;
                return out;
            },
            scale: function (out, a, v) {
                var vx = v[0];
                var vy = v[1];
                out[0] = a[0] * vx;
                out[1] = a[1] * vy;
                out[2] = a[2] * vx;
                out[3] = a[3] * vy;
                out[4] = a[4] * vx;
                out[5] = a[5] * vy;
                return out;
            },
            invert: function (out, a) {
                var aa = a[0];
                var ac = a[2];
                var atx = a[4];
                var ab = a[1];
                var ad = a[3];
                var aty = a[5];
                var det = aa * ad - ab * ac;
                if (!det) {
                    return null;
                }
                det = 1 / det;
                out[0] = ad * det;
                out[1] = -ab * det;
                out[2] = -ac * det;
                out[3] = aa * det;
                out[4] = (ac * aty - ad * atx) * det;
                out[5] = (ab * atx - aa * aty) * det;
                return out;
            }
        };
    return matrix;
});
define(&apos;echarts/component/legend/LegendModel&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../../model/Model&apos;, &apos;../../echarts&apos;], function (require) {
    &apos;use strict&apos;;
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var Model = require(&apos;../../model/Model&apos;);
    var LegendModel = require(&apos;../../echarts&apos;).extendComponentModel({
            type: &apos;legend&apos;,
            dependencies: [&apos;series&apos;],
            layoutMode: {
                type: &apos;box&apos;,
                ignoreSize: true
            },
            init: function (option, parentModel, ecModel) {
                this.mergeDefaultAndTheme(option, ecModel);
                option.selected = option.selected || {};
            },
            mergeOption: function (option) {
                LegendModel.superCall(this, &apos;mergeOption&apos;, option);
            },
            optionUpdated: function () {
                this._updateData(this.ecModel);
                var legendData = this._data;
                // If selectedMode is single, try to select one
                if (legendData[0] &amp;&amp; this.get(&apos;selectedMode&apos;) === &apos;single&apos;) {
                    var hasSelected = false;
                    // If has any selected in option.selected
                    for (var i = 0; i &lt; legendData.length; i++) {
                        var name = legendData[i].get(&apos;name&apos;);
                        if (this.isSelected(name)) {
                            // Force to unselect others
                            this.select(name);
                            hasSelected = true;
                            break;
                        }
                    }
                    // Try select the first if selectedMode is single
                    !hasSelected &amp;&amp; this.select(legendData[0].get(&apos;name&apos;));
                }
            },
            _updateData: function (ecModel) {
                var legendData = zrUtil.map(this.get(&apos;data&apos;) || [], function (dataItem) {
                        // Can be string or number
                        if (typeof dataItem === &apos;string&apos; || typeof dataItem === &apos;number&apos;) {
                            dataItem = { name: dataItem };
                        }
                        return new Model(dataItem, this, this.ecModel);
                    }, this);
                this._data = legendData;
                var availableNames = zrUtil.map(ecModel.getSeries(), function (series) {
                        return series.name;
                    });
                ecModel.eachSeries(function (seriesModel) {
                    if (seriesModel.legendDataProvider) {
                        var data = seriesModel.legendDataProvider();
                        availableNames = availableNames.concat(data.mapArray(data.getName));
                    }
                });
                /**
             * @type {Array.<string>}
             * @private
             */
                this._availableNames = availableNames;
            },
            getData: function () {
                return this._data;
            },
            select: function (name) {
                var selected = this.option.selected;
                var selectedMode = this.get(&apos;selectedMode&apos;);
                if (selectedMode === &apos;single&apos;) {
                    var data = this._data;
                    zrUtil.each(data, function (dataItem) {
                        selected[dataItem.get(&apos;name&apos;)] = false;
                    });
                }
                selected[name] = true;
            },
            unSelect: function (name) {
                if (this.get(&apos;selectedMode&apos;) !== &apos;single&apos;) {
                    this.option.selected[name] = false;
                }
            },
            toggleSelected: function (name) {
                var selected = this.option.selected;
                // Default is true
                if (!(name in selected)) {
                    selected[name] = true;
                }
                this[selected[name] ? &apos;unSelect&apos; : &apos;select&apos;](name);
            },
            isSelected: function (name) {
                var selected = this.option.selected;
                return !(name in selected &amp;&amp; !selected[name]) &amp;&amp; zrUtil.indexOf(this._availableNames, name) &gt;= 0;
            },
            defaultOption: {
                zlevel: 0,
                z: 4,
                show: true,
                orient: &apos;horizontal&apos;,
                left: &apos;center&apos;,
                top: &apos;top&apos;,
                align: &apos;auto&apos;,
                backgroundColor: &apos;rgba(0,0,0,0)&apos;,
                borderColor: &apos;#ccc&apos;,
                borderWidth: 0,
                padding: 5,
                itemGap: 10,
                itemWidth: 25,
                itemHeight: 14,
                inactiveColor: &apos;#ccc&apos;,
                textStyle: { color: &apos;#333&apos; },
                selectedMode: true,
                tooltip: { show: false }
            }
        });
    return LegendModel;
});
define(&apos;echarts/component/legend/legendFilter&apos;, [], function () {
    return function (ecModel) {
        var legendModels = ecModel.findComponents({ mainType: &apos;legend&apos; });
        if (legendModels &amp;&amp; legendModels.length) {
            ecModel.filterSeries(function (series) {
                // If in any legend component the status is not selected.
                // Because in legend series is assumed selected when it is not in the legend data.
                for (var i = 0; i &lt; legendModels.length; i++) {
                    if (!legendModels[i].isSelected(series.name)) {
                        return false;
                    }
                }
                return true;
            });
        }
    };
});
define(&apos;echarts/util/format&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;./number&apos;, &apos;zrender/contain/text&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var numberUtil = require(&apos;./number&apos;);
    var textContain = require(&apos;zrender/contain/text&apos;);
    /**
     * &#x6BCF;&#x4E09;&#x4F4D;&#x9ED8;&#x8BA4;&#x52A0;,&#x683C;&#x5F0F;&#x5316;
     * @type {string|number} x
     */
    function addCommas(x) {
        if (isNaN(x)) {
            return &apos;-&apos;;
        }
        x = (x + &apos;&apos;).split(&apos;.&apos;);
        return x[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g, &apos;$1,&apos;) + (x.length &gt; 1 ? &apos;.&apos; + x[1] : &apos;&apos;);
    }
    /**
     * @param {string} str
     * @return {string} str
     */
    function toCamelCase(str) {
        return str.toLowerCase().replace(/-(.)/g, function (match, group1) {
            return group1.toUpperCase();
        });
    }
    /**
     * Normalize css liked array configuration
     * e.g.
     *  3 =&gt; [3, 3, 3, 3]
     *  [4, 2] =&gt; [4, 2, 4, 2]
     *  [4, 3, 2] =&gt; [4, 3, 2, 3]
     * @param {number|Array.<number>} val
     */
    function normalizeCssArray(val) {
        var len = val.length;
        if (typeof val === &apos;number&apos;) {
            return [
                val,
                val,
                val,
                val
            ];
        } else if (len === 2) {
            // vertical | horizontal
            return [
                val[0],
                val[1],
                val[0],
                val[1]
            ];
        } else if (len === 3) {
            // top | horizontal | bottom
            return [
                val[0],
                val[1],
                val[2],
                val[1]
            ];
        }
        return val;
    }
    function encodeHTML(source) {
        return String(source).replace(/&amp;/g, &apos;&amp;&apos;).replace(//g, &apos;&gt;&apos;).replace(/&quot;/g, &apos;&quot;&apos;).replace(/&apos;/g, &apos;&apos;&apos;);
    }
    var TPL_VAR_ALIAS = [
            &apos;a&apos;,
            &apos;b&apos;,
            &apos;c&apos;,
            &apos;d&apos;,
            &apos;e&apos;,
            &apos;f&apos;,
            &apos;g&apos;
        ];
    function wrapVar(varName, seriesIdx) {
        return &apos;{&apos; + varName + (seriesIdx == null ? &apos;&apos; : seriesIdx) + &apos;}&apos;;
    }
    /**
     * Template formatter
     * @param  {string} tpl
     * @param  {Array.<object>|Object} paramsList
     * @return {string}
     */
    function formatTpl(tpl, paramsList) {
        if (!zrUtil.isArray(paramsList)) {
            paramsList = [paramsList];
        }
        var seriesLen = paramsList.length;
        if (!seriesLen) {
            return &apos;&apos;;
        }
        var $vars = paramsList[0].$vars || [];
        for (var i = 0; i &lt; $vars.length; i++) {
            var alias = TPL_VAR_ALIAS[i];
            tpl = tpl.replace(wrapVar(alias), wrapVar(alias, 0));
        }
        for (var seriesIdx = 0; seriesIdx &lt; seriesLen; seriesIdx++) {
            for (var k = 0; k &lt; $vars.length; k++) {
                tpl = tpl.replace(wrapVar(TPL_VAR_ALIAS[k], seriesIdx), paramsList[seriesIdx][$vars[k]]);
            }
        }
        return tpl;
    }
    /**
     * ISO Date format
     * @param {string} tpl
     * @param {number} value
     * @inner
     */
    function formatTime(tpl, value) {
        if (tpl === &apos;week&apos; || tpl === &apos;month&apos; || tpl === &apos;quarter&apos; || tpl === &apos;half-year&apos; || tpl === &apos;year&apos;) {
            tpl = &apos;MM-dd\nyyyy&apos;;
        }
        var date = numberUtil.parseDate(value);
        var y = date.getFullYear();
        var M = date.getMonth() + 1;
        var d = date.getDate();
        var h = date.getHours();
        var m = date.getMinutes();
        var s = date.getSeconds();
        tpl = tpl.replace(&apos;MM&apos;, s2d(M)).toLowerCase().replace(&apos;yyyy&apos;, y).replace(&apos;yy&apos;, y % 100).replace(&apos;dd&apos;, s2d(d)).replace(&apos;d&apos;, d).replace(&apos;hh&apos;, s2d(h)).replace(&apos;h&apos;, h).replace(&apos;mm&apos;, s2d(m)).replace(&apos;m&apos;, m).replace(&apos;ss&apos;, s2d(s)).replace(&apos;s&apos;, s);
        return tpl;
    }
    /**
     * @param {string} str
     * @return {string}
     * @inner
     */
    function s2d(str) {
        return str &lt; 10 ? &apos;0&apos; + str : str;
    }
    return {
        normalizeCssArray: normalizeCssArray,
        addCommas: addCommas,
        toCamelCase: toCamelCase,
        encodeHTML: encodeHTML,
        formatTpl: formatTpl,
        formatTime: formatTime,
        truncateText: textContain.truncateText
    };
});
define(&apos;echarts/component/legend/LegendView&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../../util/symbol&apos;, &apos;../../util/graphic&apos;, &apos;../helper/listComponent&apos;, &apos;../../echarts&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var symbolCreator = require(&apos;../../util/symbol&apos;);
    var graphic = require(&apos;../../util/graphic&apos;);
    var listComponentHelper = require(&apos;../helper/listComponent&apos;);
    var curry = zrUtil.curry;
    function dispatchSelectAction(name, api) {
        api.dispatchAction({
            type: &apos;legendToggleSelect&apos;,
            name: name
        });
    }
    function dispatchHighlightAction(seriesModel, dataName, api) {
        // If element hover will move to a hoverLayer.
        var el = api.getZr().storage.getDisplayList()[0];
        if (!(el &amp;&amp; el.useHoverLayer)) {
            seriesModel.get(&apos;legendHoverLink&apos;) &amp;&amp; api.dispatchAction({
                type: &apos;highlight&apos;,
                seriesName: seriesModel.name,
                name: dataName
            });
        }
    }
    function dispatchDownplayAction(seriesModel, dataName, api) {
        // If element hover will move to a hoverLayer.
        var el = api.getZr().storage.getDisplayList()[0];
        if (!(el &amp;&amp; el.useHoverLayer)) {
            seriesModel.get(&apos;legendHoverLink&apos;) &amp;&amp; api.dispatchAction({
                type: &apos;downplay&apos;,
                seriesName: seriesModel.name,
                name: dataName
            });
        }
    }
    return require(&apos;../../echarts&apos;).extendComponentView({
        type: &apos;legend&apos;,
        init: function () {
            this._symbolTypeStore = {};
        },
        render: function (legendModel, ecModel, api) {
            var group = this.group;
            group.removeAll();
            if (!legendModel.get(&apos;show&apos;)) {
                return;
            }
            var selectMode = legendModel.get(&apos;selectedMode&apos;);
            var itemAlign = legendModel.get(&apos;align&apos;);
            if (itemAlign === &apos;auto&apos;) {
                itemAlign = legendModel.get(&apos;left&apos;) === &apos;right&apos; &amp;&amp; legendModel.get(&apos;orient&apos;) === &apos;vertical&apos; ? &apos;right&apos; : &apos;left&apos;;
            }
            var legendDrawedMap = {};
            zrUtil.each(legendModel.getData(), function (itemModel) {
                var name = itemModel.get(&apos;name&apos;);
                // Use empty string or \n as a newline string
                if (name === &apos;&apos; || name === &apos;\n&apos;) {
                    group.add(new graphic.Group({ newline: true }));
                    return;
                }
                var seriesModel = ecModel.getSeriesByName(name)[0];
                if (legendDrawedMap[name]) {
                    // Have been drawed
                    return;
                }
                // Series legend
                if (seriesModel) {
                    var data = seriesModel.getData();
                    var color = data.getVisual(&apos;color&apos;);
                    // If color is a callback function
                    if (typeof color === &apos;function&apos;) {
                        // Use the first data
                        color = color(seriesModel.getDataParams(0));
                    }
                    // Using rect symbol defaultly
                    var legendSymbolType = data.getVisual(&apos;legendSymbol&apos;) || &apos;roundRect&apos;;
                    var symbolType = data.getVisual(&apos;symbol&apos;);
                    var itemGroup = this._createItem(name, itemModel, legendModel, legendSymbolType, symbolType, itemAlign, color, selectMode);
                    itemGroup.on(&apos;click&apos;, curry(dispatchSelectAction, name, api)).on(&apos;mouseover&apos;, curry(dispatchHighlightAction, seriesModel, &apos;&apos;, api)).on(&apos;mouseout&apos;, curry(dispatchDownplayAction, seriesModel, &apos;&apos;, api));
                    legendDrawedMap[name] = true;
                } else {
                    // Data legend of pie, funnel
                    ecModel.eachRawSeries(function (seriesModel) {
                        // In case multiple series has same data name
                        if (legendDrawedMap[name]) {
                            return;
                        }
                        if (seriesModel.legendDataProvider) {
                            var data = seriesModel.legendDataProvider();
                            var idx = data.indexOfName(name);
                            if (idx &lt; 0) {
                                return;
                            }
                            var color = data.getItemVisual(idx, &apos;color&apos;);
                            var legendSymbolType = &apos;roundRect&apos;;
                            var itemGroup = this._createItem(name, itemModel, legendModel, legendSymbolType, null, itemAlign, color, selectMode);
                            itemGroup.on(&apos;click&apos;, curry(dispatchSelectAction, name, api)).on(&apos;mouseover&apos;, curry(dispatchHighlightAction, seriesModel, name, api)).on(&apos;mouseout&apos;, curry(dispatchDownplayAction, seriesModel, name, api));
                            legendDrawedMap[name] = true;
                        }
                    }, this);
                }
                if (true) {
                    if (!legendDrawedMap[name]) {
                        console.warn(name + &apos; series not exists. Legend data should be same with series name or data name.&apos;);
                    }
                }
            }, this);
            listComponentHelper.layout(group, legendModel, api);
            // Render background after group is layout
            // FIXME
            listComponentHelper.addBackground(group, legendModel);
        },
        _createItem: function (name, itemModel, legendModel, legendSymbolType, symbolType, itemAlign, color, selectMode) {
            var itemWidth = legendModel.get(&apos;itemWidth&apos;);
            var itemHeight = legendModel.get(&apos;itemHeight&apos;);
            var inactiveColor = legendModel.get(&apos;inactiveColor&apos;);
            var isSelected = legendModel.isSelected(name);
            var itemGroup = new graphic.Group();
            var textStyleModel = itemModel.getModel(&apos;textStyle&apos;);
            var itemIcon = itemModel.get(&apos;icon&apos;);
            var tooltipModel = itemModel.getModel(&apos;tooltip&apos;);
            // Use user given icon first
            legendSymbolType = itemIcon || legendSymbolType;
            itemGroup.add(symbolCreator.createSymbol(legendSymbolType, 0, 0, itemWidth, itemHeight, isSelected ? color : inactiveColor));
            // Compose symbols
            // PENDING
            if (!itemIcon &amp;&amp; symbolType &amp;&amp; (symbolType !== legendSymbolType || symbolType == &apos;none&apos;)) {
                var size = itemHeight * 0.8;
                if (symbolType === &apos;none&apos;) {
                    symbolType = &apos;circle&apos;;
                }
                // Put symbol in the center
                itemGroup.add(symbolCreator.createSymbol(symbolType, (itemWidth - size) / 2, (itemHeight - size) / 2, size, size, isSelected ? color : inactiveColor));
            }
            // Text
            var textX = itemAlign === &apos;left&apos; ? itemWidth + 5 : -5;
            var textAlign = itemAlign;
            var formatter = legendModel.get(&apos;formatter&apos;);
            var content = name;
            if (typeof formatter === &apos;string&apos; &amp;&amp; formatter) {
                content = formatter.replace(&apos;{name}&apos;, name);
            } else if (typeof formatter === &apos;function&apos;) {
                content = formatter(name);
            }
            var text = new graphic.Text({
                    style: {
                        text: content,
                        x: textX,
                        y: itemHeight / 2,
                        fill: isSelected ? textStyleModel.getTextColor() : inactiveColor,
                        textFont: textStyleModel.getFont(),
                        textAlign: textAlign,
                        textVerticalAlign: &apos;middle&apos;
                    }
                });
            itemGroup.add(text);
            // Add a invisible rect to increase the area of mouse hover
            var hitRect = new graphic.Rect({
                    shape: itemGroup.getBoundingRect(),
                    invisible: true,
                    tooltip: tooltipModel.get(&apos;show&apos;) ? zrUtil.extend({
                        content: name,
                        formatter: function () {
                            return name;
                        },
                        formatterParams: {
                            componentType: &apos;legend&apos;,
                            legendIndex: legendModel.componentIndex,
                            name: name,
                            $vars: [&apos;name&apos;]
                        }
                    }, tooltipModel.option) : null
                });
            itemGroup.add(hitRect);
            itemGroup.eachChild(function (child) {
                child.silent = true;
            });
            hitRect.silent = !selectMode;
            this.group.add(itemGroup);
            graphic.setHoverStyle(itemGroup);
            return itemGroup;
        }
    });
});
define(&apos;echarts/util/layout&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;zrender/core/BoundingRect&apos;, &apos;./number&apos;, &apos;./format&apos;], function (require) {
    &apos;use strict&apos;;
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var BoundingRect = require(&apos;zrender/core/BoundingRect&apos;);
    var numberUtil = require(&apos;./number&apos;);
    var formatUtil = require(&apos;./format&apos;);
    var parsePercent = numberUtil.parsePercent;
    var each = zrUtil.each;
    var layout = {};
    var LOCATION_PARAMS = [
            &apos;left&apos;,
            &apos;right&apos;,
            &apos;top&apos;,
            &apos;bottom&apos;,
            &apos;width&apos;,
            &apos;height&apos;
        ];
    function boxLayout(orient, group, gap, maxWidth, maxHeight) {
        var x = 0;
        var y = 0;
        if (maxWidth == null) {
            maxWidth = Infinity;
        }
        if (maxHeight == null) {
            maxHeight = Infinity;
        }
        var currentLineMaxSize = 0;
        group.eachChild(function (child, idx) {
            var position = child.position;
            var rect = child.getBoundingRect();
            var nextChild = group.childAt(idx + 1);
            var nextChildRect = nextChild &amp;&amp; nextChild.getBoundingRect();
            var nextX;
            var nextY;
            if (orient === &apos;horizontal&apos;) {
                var moveX = rect.width + (nextChildRect ? -nextChildRect.x + rect.x : 0);
                nextX = x + moveX;
                // Wrap when width exceeds maxWidth or meet a `newline` group
                if (nextX &gt; maxWidth || child.newline) {
                    x = 0;
                    nextX = moveX;
                    y += currentLineMaxSize + gap;
                    currentLineMaxSize = rect.height;
                } else {
                    currentLineMaxSize = Math.max(currentLineMaxSize, rect.height);
                }
            } else {
                var moveY = rect.height + (nextChildRect ? -nextChildRect.y + rect.y : 0);
                nextY = y + moveY;
                // Wrap when width exceeds maxHeight or meet a `newline` group
                if (nextY &gt; maxHeight || child.newline) {
                    x += currentLineMaxSize + gap;
                    y = 0;
                    nextY = moveY;
                    currentLineMaxSize = rect.width;
                } else {
                    currentLineMaxSize = Math.max(currentLineMaxSize, rect.width);
                }
            }
            if (child.newline) {
                return;
            }
            position[0] = x;
            position[1] = y;
            orient === &apos;horizontal&apos; ? x = nextX + gap : y = nextY + gap;
        });
    }
    /**
     * VBox or HBox layouting
     * @param {string} orient
     * @param {module:zrender/container/Group} group
     * @param {number} gap
     * @param {number} [width=Infinity]
     * @param {number} [height=Infinity]
     */
    layout.box = boxLayout;
    /**
     * VBox layouting
     * @param {module:zrender/container/Group} group
     * @param {number} gap
     * @param {number} [width=Infinity]
     * @param {number} [height=Infinity]
     */
    layout.vbox = zrUtil.curry(boxLayout, &apos;vertical&apos;);
    /**
     * HBox layouting
     * @param {module:zrender/container/Group} group
     * @param {number} gap
     * @param {number} [width=Infinity]
     * @param {number} [height=Infinity]
     */
    layout.hbox = zrUtil.curry(boxLayout, &apos;horizontal&apos;);
    /**
     * If x or x2 is not specified or &apos;center&apos; &apos;left&apos; &apos;right&apos;,
     * the width would be as long as possible.
     * If y or y2 is not specified or &apos;middle&apos; &apos;top&apos; &apos;bottom&apos;,
     * the height would be as long as possible.
     *
     * @param {Object} positionInfo
     * @param {number|string} [positionInfo.x]
     * @param {number|string} [positionInfo.y]
     * @param {number|string} [positionInfo.x2]
     * @param {number|string} [positionInfo.y2]
     * @param {Object} containerRect
     * @param {string|number} margin
     * @return {Object} {width, height}
     */
    layout.getAvailableSize = function (positionInfo, containerRect, margin) {
        var containerWidth = containerRect.width;
        var containerHeight = containerRect.height;
        var x = parsePercent(positionInfo.x, containerWidth);
        var y = parsePercent(positionInfo.y, containerHeight);
        var x2 = parsePercent(positionInfo.x2, containerWidth);
        var y2 = parsePercent(positionInfo.y2, containerHeight);
        (isNaN(x) || isNaN(parseFloat(positionInfo.x))) &amp;&amp; (x = 0);
        (isNaN(x2) || isNaN(parseFloat(positionInfo.x2))) &amp;&amp; (x2 = containerWidth);
        (isNaN(y) || isNaN(parseFloat(positionInfo.y))) &amp;&amp; (y = 0);
        (isNaN(y2) || isNaN(parseFloat(positionInfo.y2))) &amp;&amp; (y2 = containerHeight);
        margin = formatUtil.normalizeCssArray(margin || 0);
        return {
            width: Math.max(x2 - x - margin[1] - margin[3], 0),
            height: Math.max(y2 - y - margin[0] - margin[2], 0)
        };
    };
    /**
     * Parse position info.
     *
     * @param {Object} positionInfo
     * @param {number|string} [positionInfo.left]
     * @param {number|string} [positionInfo.top]
     * @param {number|string} [positionInfo.right]
     * @param {number|string} [positionInfo.bottom]
     * @param {number|string} [positionInfo.width]
     * @param {number|string} [positionInfo.height]
     * @param {number|string} [positionInfo.aspect] Aspect is width / height
     * @param {Object} containerRect
     * @param {string|number} [margin]
     *
     * @return {module:zrender/core/BoundingRect}
     */
    layout.getLayoutRect = function (positionInfo, containerRect, margin) {
        margin = formatUtil.normalizeCssArray(margin || 0);
        var containerWidth = containerRect.width;
        var containerHeight = containerRect.height;
        var left = parsePercent(positionInfo.left, containerWidth);
        var top = parsePercent(positionInfo.top, containerHeight);
        var right = parsePercent(positionInfo.right, containerWidth);
        var bottom = parsePercent(positionInfo.bottom, containerHeight);
        var width = parsePercent(positionInfo.width, containerWidth);
        var height = parsePercent(positionInfo.height, containerHeight);
        var verticalMargin = margin[2] + margin[0];
        var horizontalMargin = margin[1] + margin[3];
        var aspect = positionInfo.aspect;
        // If width is not specified, calculate width from left and right
        if (isNaN(width)) {
            width = containerWidth - right - horizontalMargin - left;
        }
        if (isNaN(height)) {
            height = containerHeight - bottom - verticalMargin - top;
        }
        // If width and height are not given
        // 1. Graph should not exceeds the container
        // 2. Aspect must be keeped
        // 3. Graph should take the space as more as possible
        if (isNaN(width) &amp;&amp; isNaN(height)) {
            if (aspect &gt; containerWidth / containerHeight) {
                width = containerWidth * 0.8;
            } else {
                height = containerHeight * 0.8;
            }
        }
        if (aspect != null) {
            // Calculate width or height with given aspect
            if (isNaN(width)) {
                width = aspect * height;
            }
            if (isNaN(height)) {
                height = width / aspect;
            }
        }
        // If left is not specified, calculate left from right and width
        if (isNaN(left)) {
            left = containerWidth - right - width - horizontalMargin;
        }
        if (isNaN(top)) {
            top = containerHeight - bottom - height - verticalMargin;
        }
        // Align left and top
        switch (positionInfo.left || positionInfo.right) {
        case &apos;center&apos;:
            left = containerWidth / 2 - width / 2 - margin[3];
            break;
        case &apos;right&apos;:
            left = containerWidth - width - horizontalMargin;
            break;
        }
        switch (positionInfo.top || positionInfo.bottom) {
        case &apos;middle&apos;:
        case &apos;center&apos;:
            top = containerHeight / 2 - height / 2 - margin[0];
            break;
        case &apos;bottom&apos;:
            top = containerHeight - height - verticalMargin;
            break;
        }
        // If something is wrong and left, top, width, height are calculated as NaN
        left = left || 0;
        top = top || 0;
        if (isNaN(width)) {
            // Width may be NaN if only one value is given except width
            width = containerWidth - left - (right || 0);
        }
        if (isNaN(height)) {
            // Height may be NaN if only one value is given except height
            height = containerHeight - top - (bottom || 0);
        }
        var rect = new BoundingRect(left + margin[3], top + margin[0], width, height);
        rect.margin = margin;
        return rect;
    };
    /**
     * Position group of component in viewport
     *  Group position is specified by either
     *  {left, top}, {right, bottom}
     *  If all properties exists, right and bottom will be igonred.
     *
     * @param {module:zrender/container/Group} group
     * @param {Object} positionInfo
     * @param {number|string} [positionInfo.left]
     * @param {number|string} [positionInfo.top]
     * @param {number|string} [positionInfo.right]
     * @param {number|string} [positionInfo.bottom]
     * @param {Object} containerRect
     * @param {string|number} margin
     */
    layout.positionGroup = function (group, positionInfo, containerRect, margin) {
        var groupRect = group.getBoundingRect();
        positionInfo = zrUtil.extend(zrUtil.clone(positionInfo), {
            width: groupRect.width,
            height: groupRect.height
        });
        positionInfo = layout.getLayoutRect(positionInfo, containerRect, margin);
        group.attr(&apos;position&apos;, [
            positionInfo.x - groupRect.x,
            positionInfo.y - groupRect.y
        ]);
    };
    /**
     * Consider Case:
     * When defulat option has {left: 0, width: 100}, and we set {right: 0}
     * through setOption or media query, using normal zrUtil.merge will cause
     * {right: 0} does not take effect.
     *
     * @example
     * ComponentModel.extend({
     *     init: function () {
     *         ...
     *         var inputPositionParams = layout.getLayoutParams(option);
     *         this.mergeOption(inputPositionParams);
     *     },
     *     mergeOption: function (newOption) {
     *         newOption &amp;&amp; zrUtil.merge(thisOption, newOption, true);
     *         layout.mergeLayoutParam(thisOption, newOption);
     *     }
     * });
     *
     * @param {Object} targetOption
     * @param {Object} newOption
     * @param {Object|string} [opt]
     * @param {boolean} [opt.ignoreSize=false] Some component must has width and height.
     */
    layout.mergeLayoutParam = function (targetOption, newOption, opt) {
        !zrUtil.isObject(opt) &amp;&amp; (opt = {});
        var hNames = [
                &apos;width&apos;,
                &apos;left&apos;,
                &apos;right&apos;
            ];
        // Order by priority.
        var vNames = [
                &apos;height&apos;,
                &apos;top&apos;,
                &apos;bottom&apos;
            ];
        // Order by priority.
        var hResult = merge(hNames);
        var vResult = merge(vNames);
        copy(hNames, targetOption, hResult);
        copy(vNames, targetOption, vResult);
        function merge(names) {
            var newParams = {};
            var newValueCount = 0;
            var merged = {};
            var mergedValueCount = 0;
            var enoughParamNumber = opt.ignoreSize ? 1 : 2;
            each(names, function (name) {
                merged[name] = targetOption[name];
            });
            each(names, function (name) {
                // Consider case: newOption.width is null, which is
                // set by user for removing width setting.
                hasProp(newOption, name) &amp;&amp; (newParams[name] = merged[name] = newOption[name]);
                hasValue(newParams, name) &amp;&amp; newValueCount++;
                hasValue(merged, name) &amp;&amp; mergedValueCount++;
            });
            // Case: newOption: {width: ..., right: ...},
            // or targetOption: {right: ...} and newOption: {width: ...},
            // There is no conflict when merged only has params count
            // little than enoughParamNumber.
            if (mergedValueCount === enoughParamNumber || !newValueCount) {
                return merged;
            }    // Case: newOption: {width: ..., right: ...},
                 // Than we can make sure user only want those two, and ignore
                 // all origin params in targetOption.
            else if (newValueCount &gt;= enoughParamNumber) {
                return newParams;
            } else {
                // Chose another param from targetOption by priority.
                // When &apos;ignoreSize&apos;, enoughParamNumber is 1 and those will not happen.
                for (var i = 0; i &lt; names.length; i++) {
                    var name = names[i];
                    if (!hasProp(newParams, name) &amp;&amp; hasProp(targetOption, name)) {
                        newParams[name] = targetOption[name];
                        break;
                    }
                }
                return newParams;
            }
        }
        function hasProp(obj, name) {
            return obj.hasOwnProperty(name);
        }
        function hasValue(obj, name) {
            return obj[name] != null &amp;&amp; obj[name] !== &apos;auto&apos;;
        }
        function copy(names, target, source) {
            each(names, function (name) {
                target[name] = source[name];
            });
        }
    };
    /**
     * Retrieve &apos;left&apos;, &apos;right&apos;, &apos;top&apos;, &apos;bottom&apos;, &apos;width&apos;, &apos;height&apos; from object.
     * @param {Object} source
     * @return {Object} Result contains those props.
     */
    layout.getLayoutParams = function (source) {
        return layout.copyLayoutParams({}, source);
    };
    /**
     * Retrieve &apos;left&apos;, &apos;right&apos;, &apos;top&apos;, &apos;bottom&apos;, &apos;width&apos;, &apos;height&apos; from object.
     * @param {Object} source
     * @return {Object} Result contains those props.
     */
    layout.copyLayoutParams = function (target, source) {
        source &amp;&amp; target &amp;&amp; each(LOCATION_PARAMS, function (name) {
            source.hasOwnProperty(name) &amp;&amp; (target[name] = source[name]);
        });
        return target;
    };
    return layout;
});
define(&apos;echarts/component/legend/legendAction&apos;, [&apos;require&apos;, &apos;../../echarts&apos;, &apos;zrender/core/util&apos;], function (require) {
    var echarts = require(&apos;../../echarts&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    function legendSelectActionHandler(methodName, payload, ecModel) {
        var selectedMap = {};
        var isToggleSelect = methodName === &apos;toggleSelected&apos;;
        var isSelected;
        // Update all legend components
        ecModel.eachComponent(&apos;legend&apos;, function (legendModel) {
            if (isToggleSelect &amp;&amp; isSelected != null) {
                // Force other legend has same selected status
                // Or the first is toggled to true and other are toggled to false
                // In the case one legend has some item unSelected in option. And if other legend
                // doesn&apos;t has the item, they will assume it is selected.
                legendModel[isSelected ? &apos;select&apos; : &apos;unSelect&apos;](payload.name);
            } else {
                legendModel[methodName](payload.name);
                isSelected = legendModel.isSelected(payload.name);
            }
            var legendData = legendModel.getData();
            zrUtil.each(legendData, function (model) {
                var name = model.get(&apos;name&apos;);
                // Wrap element
                if (name === &apos;\n&apos; || name === &apos;&apos;) {
                    return;
                }
                var isItemSelected = legendModel.isSelected(name);
                if (name in selectedMap) {
                    // Unselected if any legend is unselected
                    selectedMap[name] = selectedMap[name] &amp;&amp; isItemSelected;
                } else {
                    selectedMap[name] = isItemSelected;
                }
            });
        });
        // Return the event explicitly
        return {
            name: payload.name,
            selected: selectedMap
        };
    }
    /**
     * @event legendToggleSelect
     * @type {Object}
     * @property {string} type &apos;legendToggleSelect&apos;
     * @property {string} [from]
     * @property {string} name Series name or data item name
     */
    echarts.registerAction(&apos;legendToggleSelect&apos;, &apos;legendselectchanged&apos;, zrUtil.curry(legendSelectActionHandler, &apos;toggleSelected&apos;));
    /**
     * @event legendSelect
     * @type {Object}
     * @property {string} type &apos;legendSelect&apos;
     * @property {string} name Series name or data item name
     */
    echarts.registerAction(&apos;legendSelect&apos;, &apos;legendselected&apos;, zrUtil.curry(legendSelectActionHandler, &apos;select&apos;));
    /**
     * @event legendUnSelect
     * @type {Object}
     * @property {string} type &apos;legendUnSelect&apos;
     * @property {string} name Series name or data item name
     */
    echarts.registerAction(&apos;legendUnSelect&apos;, &apos;legendunselected&apos;, zrUtil.curry(legendSelectActionHandler, &apos;unSelect&apos;));
});
define(&apos;echarts/component/tooltip/TooltipModel&apos;, [&apos;require&apos;, &apos;../../echarts&apos;], function (require) {
    require(&apos;../../echarts&apos;).extendComponentModel({
        type: &apos;tooltip&apos;,
        defaultOption: {
            zlevel: 0,
            z: 8,
            show: true,
            showContent: true,
            trigger: &apos;item&apos;,
            triggerOn: &apos;mousemove&apos;,
            alwaysShowContent: false,
            showDelay: 0,
            hideDelay: 100,
            transitionDuration: 0.4,
            enterable: false,
            backgroundColor: &apos;rgba(50,50,50,0.7)&apos;,
            borderColor: &apos;#333&apos;,
            borderRadius: 4,
            borderWidth: 0,
            padding: 5,
            extraCssText: &apos;&apos;,
            axisPointer: {
                type: &apos;line&apos;,
                axis: &apos;auto&apos;,
                animation: true,
                animationDurationUpdate: 200,
                animationEasingUpdate: &apos;exponentialOut&apos;,
                lineStyle: {
                    color: &apos;#555&apos;,
                    width: 1,
                    type: &apos;solid&apos;
                },
                crossStyle: {
                    color: &apos;#555&apos;,
                    width: 1,
                    type: &apos;dashed&apos;,
                    textStyle: {}
                },
                shadowStyle: { color: &apos;rgba(150,150,150,0.3)&apos; }
            },
            textStyle: {
                color: &apos;#fff&apos;,
                fontSize: 14
            }
        }
    });
});
define(&apos;echarts/scale/Interval&apos;, [&apos;require&apos;, &apos;../util/number&apos;, &apos;../util/format&apos;, &apos;./Scale&apos;], function (require) {
    var numberUtil = require(&apos;../util/number&apos;);
    var formatUtil = require(&apos;../util/format&apos;);
    var Scale = require(&apos;./Scale&apos;);
    var mathFloor = Math.floor;
    var mathCeil = Math.ceil;
    /**
     * @alias module:echarts/coord/scale/Interval
     * @constructor
     */
    var IntervalScale = Scale.extend({
            type: &apos;interval&apos;,
            _interval: 0,
            setExtent: function (start, end) {
                var thisExtent = this._extent;
                //start,end may be a Number like &apos;25&apos;,so...
                if (!isNaN(start)) {
                    thisExtent[0] = parseFloat(start);
                }
                if (!isNaN(end)) {
                    thisExtent[1] = parseFloat(end);
                }
            },
            unionExtent: function (other) {
                var extent = this._extent;
                other[0] &lt; extent[0] &amp;&amp; (extent[0] = other[0]);
                other[1] &gt; extent[1] &amp;&amp; (extent[1] = other[1]);
                // unionExtent may called by it&apos;s sub classes
                IntervalScale.prototype.setExtent.call(this, extent[0], extent[1]);
            },
            getInterval: function () {
                if (!this._interval) {
                    this.niceTicks();
                }
                return this._interval;
            },
            setInterval: function (interval) {
                this._interval = interval;
                // Dropped auto calculated niceExtent and use user setted extent
                // We assume user wan&apos;t to set both interval, min, max to get a better result
                this._niceExtent = this._extent.slice();
            },
            getTicks: function () {
                if (!this._interval) {
                    this.niceTicks();
                }
                var interval = this._interval;
                var extent = this._extent;
                var ticks = [];
                // Consider this case: using dataZoom toolbox, zoom and zoom.
                var safeLimit = 10000;
                if (interval) {
                    var niceExtent = this._niceExtent;
                    if (extent[0] &lt; niceExtent[0]) {
                        ticks.push(extent[0]);
                    }
                    var tick = niceExtent[0];
                    while (tick <= niceextent[1])="" {="" ticks.push(tick);="" avoid="" rounding="" error="" tick="numberUtil.round(tick" +="" interval);="" if="" (ticks.length=""> safeLimit) {
                            return [];
                        }
                    }
                    if (extent[1] &gt; niceExtent[1]) {
                        ticks.push(extent[1]);
                    }
                }
                return ticks;
            },
            getTicksLabels: function () {
                var labels = [];
                var ticks = this.getTicks();
                for (var i = 0; i &lt; ticks.length; i++) {
                    labels.push(this.getLabel(ticks[i]));
                }
                return labels;
            },
            getLabel: function (data) {
                return formatUtil.addCommas(data);
            },
            niceTicks: function (splitNumber) {
                splitNumber = splitNumber || 5;
                var extent = this._extent;
                var span = extent[1] - extent[0];
                if (!isFinite(span)) {
                    return;
                }
                // User may set axis min 0 and data are all negative
                // FIXME If it needs to reverse ?
                if (span &lt; 0) {
                    span = -span;
                    extent.reverse();
                }
                // From &quot;Nice Numbers for Graph Labels&quot; of Graphic Gems
                // var niceSpan = numberUtil.nice(span, false);
                var step = numberUtil.nice(span / splitNumber, true);
                // Niced extent inside original extent
                var niceExtent = [
                        numberUtil.round(mathCeil(extent[0] / step) * step),
                        numberUtil.round(mathFloor(extent[1] / step) * step)
                    ];
                this._interval = step;
                this._niceExtent = niceExtent;
            },
            niceExtent: function (splitNumber, fixMin, fixMax) {
                var extent = this._extent;
                // If extent start and end are same, expand them
                if (extent[0] === extent[1]) {
                    if (extent[0] !== 0) {
                        // Expand extent
                        var expandSize = extent[0];
                        // In the fowllowing case
                        //      Axis has been fixed max 100
                        //      Plus data are all 100 and axis extent are [100, 100].
                        // Extend to the both side will cause expanded max is larger than fixed max.
                        // So only expand to the smaller side.
                        if (!fixMax) {
                            extent[1] += expandSize / 2;
                            extent[0] -= expandSize / 2;
                        } else {
                            extent[0] -= expandSize / 2;
                        }
                    } else {
                        extent[1] = 1;
                    }
                }
                var span = extent[1] - extent[0];
                // If there are no data and extent are [Infinity, -Infinity]
                if (!isFinite(span)) {
                    extent[0] = 0;
                    extent[1] = 1;
                }
                this.niceTicks(splitNumber);
                // var extent = this._extent;
                var interval = this._interval;
                if (!fixMin) {
                    extent[0] = numberUtil.round(mathFloor(extent[0] / interval) * interval);
                }
                if (!fixMax) {
                    extent[1] = numberUtil.round(mathCeil(extent[1] / interval) * interval);
                }
            }
        });
    /**
     * @return {module:echarts/scale/Time}
     */
    IntervalScale.create = function () {
        return new IntervalScale();
    };
    return IntervalScale;
});
define(&apos;echarts/component/tooltip/TooltipView&apos;, [&apos;require&apos;, &apos;./TooltipContent&apos;, &apos;../../util/graphic&apos;, &apos;zrender/core/util&apos;, &apos;../../util/format&apos;, &apos;../../util/number&apos;, &apos;zrender/core/env&apos;, &apos;../../model/Model&apos;, &apos;../../echarts&apos;], function (require) {
    var TooltipContent = require(&apos;./TooltipContent&apos;);
    var graphic = require(&apos;../../util/graphic&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var formatUtil = require(&apos;../../util/format&apos;);
    var numberUtil = require(&apos;../../util/number&apos;);
    var parsePercent = numberUtil.parsePercent;
    var env = require(&apos;zrender/core/env&apos;);
    var Model = require(&apos;../../model/Model&apos;);
    function dataEqual(a, b) {
        if (!a || !b) {
            return false;
        }
        var round = numberUtil.round;
        return round(a[0]) === round(b[0]) &amp;&amp; round(a[1]) === round(b[1]);
    }
    /**
     * @inner
     */
    function makeLineShape(x1, y1, x2, y2) {
        return {
            x1: x1,
            y1: y1,
            x2: x2,
            y2: y2
        };
    }
    /**
     * @inner
     */
    function makeRectShape(x, y, width, height) {
        return {
            x: x,
            y: y,
            width: width,
            height: height
        };
    }
    /**
     * @inner
     */
    function makeSectorShape(cx, cy, r0, r, startAngle, endAngle) {
        return {
            cx: cx,
            cy: cy,
            r0: r0,
            r: r,
            startAngle: startAngle,
            endAngle: endAngle,
            clockwise: true
        };
    }
    function refixTooltipPosition(x, y, el, viewWidth, viewHeight) {
        var width = el.clientWidth;
        var height = el.clientHeight;
        var gap = 20;
        if (x + width + gap &gt; viewWidth) {
            x -= width + gap;
        } else {
            x += gap;
        }
        if (y + height + gap &gt; viewHeight) {
            y -= height + gap;
        } else {
            y += gap;
        }
        return [
            x,
            y
        ];
    }
    function calcTooltipPosition(position, rect, dom) {
        var domWidth = dom.clientWidth;
        var domHeight = dom.clientHeight;
        var gap = 5;
        var x = 0;
        var y = 0;
        var rectWidth = rect.width;
        var rectHeight = rect.height;
        switch (position) {
        case &apos;inside&apos;:
            x = rect.x + rectWidth / 2 - domWidth / 2;
            y = rect.y + rectHeight / 2 - domHeight / 2;
            break;
        case &apos;top&apos;:
            x = rect.x + rectWidth / 2 - domWidth / 2;
            y = rect.y - domHeight - gap;
            break;
        case &apos;bottom&apos;:
            x = rect.x + rectWidth / 2 - domWidth / 2;
            y = rect.y + rectHeight + gap;
            break;
        case &apos;left&apos;:
            x = rect.x - domWidth - gap;
            y = rect.y + rectHeight / 2 - domHeight / 2;
            break;
        case &apos;right&apos;:
            x = rect.x + rectWidth + gap;
            y = rect.y + rectHeight / 2 - domHeight / 2;
        }
        return [
            x,
            y
        ];
    }
    /**
     * @param  {string|Function|Array.<number>} positionExpr
     * @param  {number} x Mouse x
     * @param  {number} y Mouse y
     * @param  {module:echarts/component/tooltip/TooltipContent} content
     * @param  {Object|<array.<object>} params
     * @param  {module:zrender/Element} el target element
     * @param  {module:echarts/ExtensionAPI} api
     * @return {Array.<number>}
     */
    function updatePosition(positionExpr, x, y, content, params, el, api) {
        var viewWidth = api.getWidth();
        var viewHeight = api.getHeight();
        var rect = el &amp;&amp; el.getBoundingRect().clone();
        el &amp;&amp; rect.applyTransform(el.transform);
        if (typeof positionExpr === &apos;function&apos;) {
            // Callback of position can be an array or a string specify the position
            positionExpr = positionExpr([
                x,
                y
            ], params, content.el, rect);
        }
        if (zrUtil.isArray(positionExpr)) {
            x = parsePercent(positionExpr[0], viewWidth);
            y = parsePercent(positionExpr[1], viewHeight);
        }    // Specify tooltip position by string &apos;top&apos; &apos;bottom&apos; &apos;left&apos; &apos;right&apos; around graphic element
        else if (typeof positionExpr === &apos;string&apos; &amp;&amp; el) {
            var pos = calcTooltipPosition(positionExpr, rect, content.el);
            x = pos[0];
            y = pos[1];
        } else {
            var pos = refixTooltipPosition(x, y, content.el, viewWidth, viewHeight);
            x = pos[0];
            y = pos[1];
        }
        content.moveTo(x, y);
    }
    function ifSeriesSupportAxisTrigger(seriesModel) {
        var coordSys = seriesModel.coordinateSystem;
        var trigger = seriesModel.get(&apos;tooltip.trigger&apos;, true);
        // Ignore series use item tooltip trigger and series coordinate system is not cartesian or
        return !(!coordSys || coordSys.type !== &apos;cartesian2d&apos; &amp;&amp; coordSys.type !== &apos;polar&apos; &amp;&amp; coordSys.type !== &apos;singleAxis&apos; || trigger === &apos;item&apos;);
    }
    require(&apos;../../echarts&apos;).extendComponentView({
        type: &apos;tooltip&apos;,
        _axisPointers: {},
        init: function (ecModel, api) {
            if (env.node) {
                return;
            }
            var tooltipContent = new TooltipContent(api.getDom(), api);
            this._tooltipContent = tooltipContent;
            api.on(&apos;showTip&apos;, this._manuallyShowTip, this);
            api.on(&apos;hideTip&apos;, this._manuallyHideTip, this);
        },
        render: function (tooltipModel, ecModel, api) {
            if (env.node) {
                return;
            }
            // Reset
            this.group.removeAll();
            /**
             * @type {Object}
             * @private
             */
            this._axisPointers = {};
            /**
             * @private
             * @type {module:echarts/component/tooltip/TooltipModel}
             */
            this._tooltipModel = tooltipModel;
            /**
             * @private
             * @type {module:echarts/model/Global}
             */
            this._ecModel = ecModel;
            /**
             * @private
             * @type {module:echarts/ExtensionAPI}
             */
            this._api = api;
            /**
             * @type {Object}
             * @private
             */
            this._lastHover = {};
            var tooltipContent = this._tooltipContent;
            tooltipContent.update();
            tooltipContent.enterable = tooltipModel.get(&apos;enterable&apos;);
            this._alwaysShowContent = tooltipModel.get(&apos;alwaysShowContent&apos;);
            /**
             * @type {Object.<string, array="">}
             */
            this._seriesGroupByAxis = this._prepareAxisTriggerData(tooltipModel, ecModel);
            var crossText = this._crossText;
            if (crossText) {
                this.group.add(crossText);
            }
            // Try to keep the tooltip show when refreshing
            if (this._lastX != null &amp;&amp; this._lastY != null) {
                var self = this;
                clearTimeout(this._refreshUpdateTimeout);
                this._refreshUpdateTimeout = setTimeout(function () {
                    // Show tip next tick after other charts are rendered
                    // In case highlight action has wrong result
                    // FIXME
                    self._manuallyShowTip({
                        x: self._lastX,
                        y: self._lastY
                    });
                });
            }
            var zr = this._api.getZr();
            zr.off(&apos;click&apos;, this._tryShow);
            zr.off(&apos;mousemove&apos;, this._mousemove);
            zr.off(&apos;mouseout&apos;, this._hide);
            zr.off(&apos;globalout&apos;, this._hide);
            if (tooltipModel.get(&apos;triggerOn&apos;) === &apos;click&apos;) {
                zr.on(&apos;click&apos;, this._tryShow, this);
            } else {
                zr.on(&apos;mousemove&apos;, this._mousemove, this);
                zr.on(&apos;mouseout&apos;, this._hide, this);
                zr.on(&apos;globalout&apos;, this._hide, this);
            }
        },
        _mousemove: function (e) {
            var showDelay = this._tooltipModel.get(&apos;showDelay&apos;);
            var self = this;
            clearTimeout(this._showTimeout);
            if (showDelay &gt; 0) {
                this._showTimeout = setTimeout(function () {
                    self._tryShow(e);
                }, showDelay);
            } else {
                this._tryShow(e);
            }
        },
        _manuallyShowTip: function (event) {
            // From self
            if (event.from === this.uid) {
                return;
            }
            var ecModel = this._ecModel;
            var seriesIndex = event.seriesIndex;
            var dataIndex = event.dataIndex;
            var seriesModel = ecModel.getSeriesByIndex(seriesIndex);
            var api = this._api;
            if (event.x == null || event.y == null) {
                if (!seriesModel) {
                    // Find the first series can use axis trigger
                    ecModel.eachSeries(function (_series) {
                        if (ifSeriesSupportAxisTrigger(_series) &amp;&amp; !seriesModel) {
                            seriesModel = _series;
                        }
                    });
                }
                if (seriesModel) {
                    var data = seriesModel.getData();
                    if (dataIndex == null) {
                        dataIndex = data.indexOfName(event.name);
                    }
                    var el = data.getItemGraphicEl(dataIndex);
                    var cx, cy;
                    // Try to get the point in coordinate system
                    var coordSys = seriesModel.coordinateSystem;
                    if (coordSys &amp;&amp; coordSys.dataToPoint) {
                        var point = coordSys.dataToPoint(data.getValues(zrUtil.map(coordSys.dimensions, function (dim) {
                                return seriesModel.coordDimToDataDim(dim)[0];
                            }), dataIndex, true));
                        cx = point &amp;&amp; point[0];
                        cy = point &amp;&amp; point[1];
                    } else if (el) {
                        // Use graphic bounding rect
                        var rect = el.getBoundingRect().clone();
                        rect.applyTransform(el.transform);
                        cx = rect.x + rect.width / 2;
                        cy = rect.y + rect.height / 2;
                    }
                    if (cx != null &amp;&amp; cy != null) {
                        this._tryShow({
                            offsetX: cx,
                            offsetY: cy,
                            target: el,
                            event: {}
                        });
                    }
                }
            } else {
                var el = api.getZr().handler.findHover(event.x, event.y);
                this._tryShow({
                    offsetX: event.x,
                    offsetY: event.y,
                    target: el,
                    event: {}
                });
            }
        },
        _manuallyHideTip: function (e) {
            if (e.from === this.uid) {
                return;
            }
            this._hide();
        },
        _prepareAxisTriggerData: function (tooltipModel, ecModel) {
            // Prepare data for axis trigger
            var seriesGroupByAxis = {};
            ecModel.eachSeries(function (seriesModel) {
                if (ifSeriesSupportAxisTrigger(seriesModel)) {
                    var coordSys = seriesModel.coordinateSystem;
                    var baseAxis;
                    var key;
                    // Only cartesian2d, polar and single support axis trigger
                    if (coordSys.type === &apos;cartesian2d&apos;) {
                        // FIXME `axisPointer.axis` is not baseAxis
                        baseAxis = coordSys.getBaseAxis();
                        key = baseAxis.dim + baseAxis.index;
                    } else if (coordSys.type === &apos;singleAxis&apos;) {
                        baseAxis = coordSys.getAxis();
                        key = baseAxis.dim + baseAxis.type;
                    } else {
                        baseAxis = coordSys.getBaseAxis();
                        key = baseAxis.dim + coordSys.name;
                    }
                    seriesGroupByAxis[key] = seriesGroupByAxis[key] || {
                        coordSys: [],
                        series: []
                    };
                    seriesGroupByAxis[key].coordSys.push(coordSys);
                    seriesGroupByAxis[key].series.push(seriesModel);
                }
            }, this);
            return seriesGroupByAxis;
        },
        _tryShow: function (e) {
            var el = e.target;
            var tooltipModel = this._tooltipModel;
            var globalTrigger = tooltipModel.get(&apos;trigger&apos;);
            var ecModel = this._ecModel;
            var api = this._api;
            if (!tooltipModel) {
                return;
            }
            // Save mouse x, mouse y. So we can try to keep showing the tip if chart is refreshed
            this._lastX = e.offsetX;
            this._lastY = e.offsetY;
            // Always show item tooltip if mouse is on the element with dataIndex
            if (el &amp;&amp; el.dataIndex != null) {
                // Use dataModel in element if possible
                // Used when mouseover on a element like markPoint or edge
                // In which case, the data is not main data in series.
                var dataModel = el.dataModel || ecModel.getSeriesByIndex(el.seriesIndex);
                var dataIndex = el.dataIndex;
                var itemModel = dataModel.getData().getItemModel(dataIndex);
                // Series or single data may use item trigger when global is axis trigger
                if ((itemModel.get(&apos;tooltip.trigger&apos;) || globalTrigger) === &apos;axis&apos;) {
                    this._showAxisTooltip(tooltipModel, ecModel, e);
                } else {
                    // Reset ticket
                    this._ticket = &apos;&apos;;
                    // If either single data or series use item trigger
                    this._hideAxisPointer();
                    // Reset last hover and dispatch downplay action
                    this._resetLastHover();
                    this._showItemTooltipContent(dataModel, dataIndex, el.dataType, e);
                }
                api.dispatchAction({
                    type: &apos;showTip&apos;,
                    from: this.uid,
                    dataIndex: el.dataIndex,
                    seriesIndex: el.seriesIndex
                });
            }    // Tooltip provided directly. Like legend
            else if (el &amp;&amp; el.tooltip) {
                var tooltipOpt = el.tooltip;
                if (typeof tooltipOpt === &apos;string&apos;) {
                    var content = tooltipOpt;
                    tooltipOpt = {
                        content: content,
                        formatter: content
                    };
                }
                var subTooltipModel = new Model(tooltipOpt, tooltipModel);
                var defaultHtml = subTooltipModel.get(&apos;content&apos;);
                var asyncTicket = Math.random();
                this._showTooltipContent(subTooltipModel, defaultHtml, subTooltipModel.get(&apos;formatterParams&apos;) || {}, asyncTicket, e.offsetX, e.offsetY, el, api);
            } else {
                if (globalTrigger === &apos;item&apos;) {
                    this._hide();
                } else {
                    // Try show axis tooltip
                    this._showAxisTooltip(tooltipModel, ecModel, e);
                }
                // Action of cross pointer
                // other pointer types will trigger action in _dispatchAndShowSeriesTooltipContent method
                if (tooltipModel.get(&apos;axisPointer.type&apos;) === &apos;cross&apos;) {
                    api.dispatchAction({
                        type: &apos;showTip&apos;,
                        from: this.uid,
                        x: e.offsetX,
                        y: e.offsetY
                    });
                }
            }
        },
        _showAxisTooltip: function (tooltipModel, ecModel, e) {
            var axisPointerModel = tooltipModel.getModel(&apos;axisPointer&apos;);
            var axisPointerType = axisPointerModel.get(&apos;type&apos;);
            if (axisPointerType === &apos;cross&apos;) {
                var el = e.target;
                if (el &amp;&amp; el.dataIndex != null) {
                    var seriesModel = ecModel.getSeriesByIndex(el.seriesIndex);
                    var dataIndex = el.dataIndex;
                    this._showItemTooltipContent(seriesModel, dataIndex, el.dataType, e);
                }
            }
            this._showAxisPointer();
            var allNotShow = true;
            zrUtil.each(this._seriesGroupByAxis, function (seriesCoordSysSameAxis) {
                // Try show the axis pointer
                var allCoordSys = seriesCoordSysSameAxis.coordSys;
                var coordSys = allCoordSys[0];
                // If mouse position is not in the grid or polar
                var point = [
                        e.offsetX,
                        e.offsetY
                    ];
                if (!coordSys.containPoint(point)) {
                    // Hide axis pointer
                    this._hideAxisPointer(coordSys.name);
                    return;
                }
                allNotShow = false;
                // Make sure point is discrete on cateogry axis
                var dimensions = coordSys.dimensions;
                var value = coordSys.pointToData(point, true);
                point = coordSys.dataToPoint(value);
                var baseAxis = coordSys.getBaseAxis();
                var axisType = axisPointerModel.get(&apos;axis&apos;);
                if (axisType === &apos;auto&apos;) {
                    axisType = baseAxis.dim;
                }
                var contentNotChange = false;
                var lastHover = this._lastHover;
                if (axisPointerType === &apos;cross&apos;) {
                    // If hover data not changed
                    // Possible when two axes are all category
                    if (dataEqual(lastHover.data, value)) {
                        contentNotChange = true;
                    }
                    lastHover.data = value;
                } else {
                    var valIndex = zrUtil.indexOf(dimensions, axisType);
                    // If hover data not changed on the axis dimension
                    if (lastHover.data === value[valIndex]) {
                        contentNotChange = true;
                    }
                    lastHover.data = value[valIndex];
                }
                if (coordSys.type === &apos;cartesian2d&apos; &amp;&amp; !contentNotChange) {
                    this._showCartesianPointer(axisPointerModel, coordSys, axisType, point);
                } else if (coordSys.type === &apos;polar&apos; &amp;&amp; !contentNotChange) {
                    this._showPolarPointer(axisPointerModel, coordSys, axisType, point);
                } else if (coordSys.type === &apos;singleAxis&apos; &amp;&amp; !contentNotChange) {
                    this._showSinglePointer(axisPointerModel, coordSys, axisType, point);
                }
                if (axisPointerType !== &apos;cross&apos;) {
                    this._dispatchAndShowSeriesTooltipContent(coordSys, seriesCoordSysSameAxis.series, point, value, contentNotChange);
                }
            }, this);
            if (!this._tooltipModel.get(&apos;show&apos;)) {
                this._hideAxisPointer();
            }
            if (allNotShow) {
                this._hide();
            }
        },
        _showCartesianPointer: function (axisPointerModel, cartesian, axisType, point) {
            var self = this;
            var axisPointerType = axisPointerModel.get(&apos;type&apos;);
            var baseAxis = cartesian.getBaseAxis();
            var moveAnimation = axisPointerType !== &apos;cross&apos; &amp;&amp; baseAxis.type === &apos;category&apos; &amp;&amp; baseAxis.getBandWidth() &gt; 20;
            if (axisPointerType === &apos;cross&apos;) {
                moveGridLine(&apos;x&apos;, point, cartesian.getAxis(&apos;y&apos;).getGlobalExtent());
                moveGridLine(&apos;y&apos;, point, cartesian.getAxis(&apos;x&apos;).getGlobalExtent());
                this._updateCrossText(cartesian, point, axisPointerModel);
            } else {
                var otherAxis = cartesian.getAxis(axisType === &apos;x&apos; ? &apos;y&apos; : &apos;x&apos;);
                var otherExtent = otherAxis.getGlobalExtent();
                if (cartesian.type === &apos;cartesian2d&apos;) {
                    (axisPointerType === &apos;line&apos; ? moveGridLine : moveGridShadow)(axisType, point, otherExtent);
                }
            }
            /**
             * @inner
             */
            function moveGridLine(axisType, point, otherExtent) {
                var targetShape = axisType === &apos;x&apos; ? makeLineShape(point[0], otherExtent[0], point[0], otherExtent[1]) : makeLineShape(otherExtent[0], point[1], otherExtent[1], point[1]);
                var pointerEl = self._getPointerElement(cartesian, axisPointerModel, axisType, targetShape);
                graphic.subPixelOptimizeLine({
                    shape: targetShape,
                    style: pointerEl.style
                });
                moveAnimation ? graphic.updateProps(pointerEl, { shape: targetShape }, axisPointerModel) : pointerEl.attr({ shape: targetShape });
            }
            /**
             * @inner
             */
            function moveGridShadow(axisType, point, otherExtent) {
                var axis = cartesian.getAxis(axisType);
                var bandWidth = axis.getBandWidth();
                var span = otherExtent[1] - otherExtent[0];
                var targetShape = axisType === &apos;x&apos; ? makeRectShape(point[0] - bandWidth / 2, otherExtent[0], bandWidth, span) : makeRectShape(otherExtent[0], point[1] - bandWidth / 2, span, bandWidth);
                var pointerEl = self._getPointerElement(cartesian, axisPointerModel, axisType, targetShape);
                moveAnimation ? graphic.updateProps(pointerEl, { shape: targetShape }, axisPointerModel) : pointerEl.attr({ shape: targetShape });
            }
        },
        _showSinglePointer: function (axisPointerModel, single, axisType, point) {
            var self = this;
            var axisPointerType = axisPointerModel.get(&apos;type&apos;);
            var moveAnimation = axisPointerType !== &apos;cross&apos; &amp;&amp; single.getBaseAxis().type === &apos;category&apos;;
            var rect = single.getRect();
            var otherExtent = [
                    rect.y,
                    rect.y + rect.height
                ];
            moveSingleLine(axisType, point, otherExtent);
            /**
             * @inner
             */
            function moveSingleLine(axisType, point, otherExtent) {
                var axis = single.getAxis();
                var orient = axis.orient;
                var targetShape = orient === &apos;horizontal&apos; ? makeLineShape(point[0], otherExtent[0], point[0], otherExtent[1]) : makeLineShape(otherExtent[0], point[1], otherExtent[1], point[1]);
                var pointerEl = self._getPointerElement(single, axisPointerModel, axisType, targetShape);
                moveAnimation ? graphic.updateProps(pointerEl, { shape: targetShape }, axisPointerModel) : pointerEl.attr({ shape: targetShape });
            }
        },
        _showPolarPointer: function (axisPointerModel, polar, axisType, point) {
            var self = this;
            var axisPointerType = axisPointerModel.get(&apos;type&apos;);
            var angleAxis = polar.getAngleAxis();
            var radiusAxis = polar.getRadiusAxis();
            var moveAnimation = axisPointerType !== &apos;cross&apos; &amp;&amp; polar.getBaseAxis().type === &apos;category&apos;;
            if (axisPointerType === &apos;cross&apos;) {
                movePolarLine(&apos;angle&apos;, point, radiusAxis.getExtent());
                movePolarLine(&apos;radius&apos;, point, angleAxis.getExtent());
                this._updateCrossText(polar, point, axisPointerModel);
            } else {
                var otherAxis = polar.getAxis(axisType === &apos;radius&apos; ? &apos;angle&apos; : &apos;radius&apos;);
                var otherExtent = otherAxis.getExtent();
                (axisPointerType === &apos;line&apos; ? movePolarLine : movePolarShadow)(axisType, point, otherExtent);
            }
            /**
             * @inner
             */
            function movePolarLine(axisType, point, otherExtent) {
                var mouseCoord = polar.pointToCoord(point);
                var targetShape;
                if (axisType === &apos;angle&apos;) {
                    var p1 = polar.coordToPoint([
                            otherExtent[0],
                            mouseCoord[1]
                        ]);
                    var p2 = polar.coordToPoint([
                            otherExtent[1],
                            mouseCoord[1]
                        ]);
                    targetShape = makeLineShape(p1[0], p1[1], p2[0], p2[1]);
                } else {
                    targetShape = {
                        cx: polar.cx,
                        cy: polar.cy,
                        r: mouseCoord[0]
                    };
                }
                var pointerEl = self._getPointerElement(polar, axisPointerModel, axisType, targetShape);
                moveAnimation ? graphic.updateProps(pointerEl, { shape: targetShape }, axisPointerModel) : pointerEl.attr({ shape: targetShape });
            }
            /**
             * @inner
             */
            function movePolarShadow(axisType, point, otherExtent) {
                var axis = polar.getAxis(axisType);
                var bandWidth = axis.getBandWidth();
                var mouseCoord = polar.pointToCoord(point);
                var targetShape;
                var radian = Math.PI / 180;
                if (axisType === &apos;angle&apos;) {
                    targetShape = makeSectorShape(polar.cx, polar.cy, otherExtent[0], otherExtent[1], (-mouseCoord[1] - bandWidth / 2) * radian, (-mouseCoord[1] + bandWidth / 2) * radian);
                } else {
                    targetShape = makeSectorShape(polar.cx, polar.cy, mouseCoord[0] - bandWidth / 2, mouseCoord[0] + bandWidth / 2, 0, Math.PI * 2);
                }
                var pointerEl = self._getPointerElement(polar, axisPointerModel, axisType, targetShape);
                moveAnimation ? graphic.updateProps(pointerEl, { shape: targetShape }, axisPointerModel) : pointerEl.attr({ shape: targetShape });
            }
        },
        _updateCrossText: function (coordSys, point, axisPointerModel) {
            var crossStyleModel = axisPointerModel.getModel(&apos;crossStyle&apos;);
            var textStyleModel = crossStyleModel.getModel(&apos;textStyle&apos;);
            var tooltipModel = this._tooltipModel;
            var text = this._crossText;
            if (!text) {
                text = this._crossText = new graphic.Text({
                    style: {
                        textAlign: &apos;left&apos;,
                        textVerticalAlign: &apos;bottom&apos;
                    }
                });
                this.group.add(text);
            }
            var value = coordSys.pointToData(point);
            var dims = coordSys.dimensions;
            value = zrUtil.map(value, function (val, idx) {
                var axis = coordSys.getAxis(dims[idx]);
                if (axis.type === &apos;category&apos; || axis.type === &apos;time&apos;) {
                    val = axis.scale.getLabel(val);
                } else {
                    val = formatUtil.addCommas(val.toFixed(axis.getPixelPrecision()));
                }
                return val;
            });
            text.setStyle({
                fill: textStyleModel.getTextColor() || crossStyleModel.get(&apos;color&apos;),
                textFont: textStyleModel.getFont(),
                text: value.join(&apos;, &apos;),
                x: point[0] + 5,
                y: point[1] - 5
            });
            text.z = tooltipModel.get(&apos;z&apos;);
            text.zlevel = tooltipModel.get(&apos;zlevel&apos;);
        },
        _getPointerElement: function (coordSys, pointerModel, axisType, initShape) {
            var tooltipModel = this._tooltipModel;
            var z = tooltipModel.get(&apos;z&apos;);
            var zlevel = tooltipModel.get(&apos;zlevel&apos;);
            var axisPointers = this._axisPointers;
            var coordSysName = coordSys.name;
            axisPointers[coordSysName] = axisPointers[coordSysName] || {};
            if (axisPointers[coordSysName][axisType]) {
                return axisPointers[coordSysName][axisType];
            }
            // Create if not exists
            var pointerType = pointerModel.get(&apos;type&apos;);
            var styleModel = pointerModel.getModel(pointerType + &apos;Style&apos;);
            var isShadow = pointerType === &apos;shadow&apos;;
            var style = styleModel[isShadow ? &apos;getAreaStyle&apos; : &apos;getLineStyle&apos;]();
            var elementType = coordSys.type === &apos;polar&apos; ? isShadow ? &apos;Sector&apos; : axisType === &apos;radius&apos; ? &apos;Circle&apos; : &apos;Line&apos; : isShadow ? &apos;Rect&apos; : &apos;Line&apos;;
            isShadow ? style.stroke = null : style.fill = null;
            var el = axisPointers[coordSysName][axisType] = new graphic[elementType]({
                    style: style,
                    z: z,
                    zlevel: zlevel,
                    silent: true,
                    shape: initShape
                });
            this.group.add(el);
            return el;
        },
        _dispatchAndShowSeriesTooltipContent: function (coordSys, seriesList, point, value, contentNotChange) {
            var rootTooltipModel = this._tooltipModel;
            var baseAxis = coordSys.getBaseAxis();
            var baseDimIndex = baseAxis.dim === &apos;x&apos; || baseAxis.dim === &apos;radius&apos; ? 0 : 1;
            var payloadBatch = zrUtil.map(seriesList, function (series) {
                    return {
                        seriesIndex: series.seriesIndex,
                        dataIndex: series.getAxisTooltipDataIndex ? series.getAxisTooltipDataIndex(series.coordDimToDataDim(baseAxis.dim), value, baseAxis) : series.getData().indexOfNearest(series.coordDimToDataDim(baseAxis.dim)[0], value[baseDimIndex], false, baseAxis.type === &apos;category&apos; ? 0.5 : null)
                    };
                });
            var lastHover = this._lastHover;
            var api = this._api;
            // Dispatch downplay action
            if (lastHover.payloadBatch &amp;&amp; !contentNotChange) {
                api.dispatchAction({
                    type: &apos;downplay&apos;,
                    batch: lastHover.payloadBatch
                });
            }
            // Dispatch highlight action
            if (!contentNotChange) {
                api.dispatchAction({
                    type: &apos;highlight&apos;,
                    batch: payloadBatch
                });
                lastHover.payloadBatch = payloadBatch;
            }
            // Dispatch showTip action
            api.dispatchAction({
                type: &apos;showTip&apos;,
                dataIndex: payloadBatch[0].dataIndex,
                seriesIndex: payloadBatch[0].seriesIndex,
                from: this.uid
            });
            if (baseAxis &amp;&amp; rootTooltipModel.get(&apos;showContent&apos;) &amp;&amp; rootTooltipModel.get(&apos;show&apos;)) {
                var paramsList = zrUtil.map(seriesList, function (series, index) {
                        return series.getDataParams(payloadBatch[index].dataIndex);
                    });
                if (!contentNotChange) {
                    // Update html content
                    var firstDataIndex = payloadBatch[0].dataIndex;
                    // Default tooltip content
                    // FIXME
                    // (1) shold be the first data which has name?
                    // (2) themeRiver, firstDataIndex is array, and first line is unnecessary.
                    var firstLine = baseAxis.type === &apos;time&apos; ? baseAxis.scale.getLabel(value[baseDimIndex]) : seriesList[0].getData().getName(firstDataIndex);
                    var defaultHtml = (firstLine ? firstLine + &apos;<br>&apos; : &apos;&apos;) + zrUtil.map(seriesList, function (series, index) {
                            return series.formatTooltip(payloadBatch[index].dataIndex, true);
                        }).join(&apos;<br>&apos;);
                    var asyncTicket = &apos;axis_&apos; + coordSys.name + &apos;_&apos; + firstDataIndex;
                    this._showTooltipContent(rootTooltipModel, defaultHtml, paramsList, asyncTicket, point[0], point[1], null, api);
                } else {
                    updatePosition(rootTooltipModel.get(&apos;position&apos;), point[0], point[1], this._tooltipContent, paramsList, null, api);
                }
            }
        },
        _showItemTooltipContent: function (seriesModel, dataIndex, dataType, e) {
            // FIXME Graph data
            var api = this._api;
            var data = seriesModel.getData(dataType);
            var itemModel = data.getItemModel(dataIndex);
            var tooltipOpt = itemModel.get(&apos;tooltip&apos;, true);
            if (typeof tooltipOpt === &apos;string&apos;) {
                // In each data item tooltip can be simply write:
                // {
                //  value: 10,
                //  tooltip: &apos;Something you need to know&apos;
                // }
                var tooltipContent = tooltipOpt;
                tooltipOpt = { formatter: tooltipContent };
            }
            var rootTooltipModel = this._tooltipModel;
            var seriesTooltipModel = seriesModel.getModel(&apos;tooltip&apos;, rootTooltipModel);
            var tooltipModel = new Model(tooltipOpt, seriesTooltipModel, seriesTooltipModel.ecModel);
            var params = seriesModel.getDataParams(dataIndex, dataType);
            var defaultHtml = seriesModel.formatTooltip(dataIndex, false, dataType);
            var asyncTicket = &apos;item_&apos; + seriesModel.name + &apos;_&apos; + dataIndex;
            this._showTooltipContent(tooltipModel, defaultHtml, params, asyncTicket, e.offsetX, e.offsetY, e.target, api);
        },
        _showTooltipContent: function (tooltipModel, defaultHtml, params, asyncTicket, x, y, target, api) {
            // Reset ticket
            this._ticket = &apos;&apos;;
            if (tooltipModel.get(&apos;showContent&apos;) &amp;&amp; tooltipModel.get(&apos;show&apos;)) {
                var tooltipContent = this._tooltipContent;
                var formatter = tooltipModel.get(&apos;formatter&apos;);
                var positionExpr = tooltipModel.get(&apos;position&apos;);
                var html = defaultHtml;
                if (formatter) {
                    if (typeof formatter === &apos;string&apos;) {
                        html = formatUtil.formatTpl(formatter, params);
                    } else if (typeof formatter === &apos;function&apos;) {
                        var self = this;
                        var ticket = asyncTicket;
                        var callback = function (cbTicket, html) {
                            if (cbTicket === self._ticket) {
                                tooltipContent.setContent(html);
                                updatePosition(positionExpr, x, y, tooltipContent, params, target, api);
                            }
                        };
                        self._ticket = ticket;
                        html = formatter(params, ticket, callback);
                    }
                }
                tooltipContent.show(tooltipModel);
                tooltipContent.setContent(html);
                updatePosition(positionExpr, x, y, tooltipContent, params, target, api);
            }
        },
        _showAxisPointer: function (coordSysName) {
            if (coordSysName) {
                var axisPointers = this._axisPointers[coordSysName];
                axisPointers &amp;&amp; zrUtil.each(axisPointers, function (el) {
                    el.show();
                });
            } else {
                this.group.eachChild(function (child) {
                    child.show();
                });
                this.group.show();
            }
        },
        _resetLastHover: function () {
            var lastHover = this._lastHover;
            if (lastHover.payloadBatch) {
                this._api.dispatchAction({
                    type: &apos;downplay&apos;,
                    batch: lastHover.payloadBatch
                });
            }
            // Reset lastHover
            this._lastHover = {};
        },
        _hideAxisPointer: function (coordSysName) {
            if (coordSysName) {
                var axisPointers = this._axisPointers[coordSysName];
                axisPointers &amp;&amp; zrUtil.each(axisPointers, function (el) {
                    el.hide();
                });
            } else {
                if (this.group.children().length) {
                    this.group.hide();
                }
            }
        },
        _hide: function () {
            clearTimeout(this._showTimeout);
            this._hideAxisPointer();
            this._resetLastHover();
            if (!this._alwaysShowContent) {
                this._tooltipContent.hideLater(this._tooltipModel.get(&apos;hideDelay&apos;));
            }
            this._api.dispatchAction({
                type: &apos;hideTip&apos;,
                from: this.uid
            });
            this._lastX = this._lastY = null;
        },
        dispose: function (ecModel, api) {
            if (env.node) {
                return;
            }
            var zr = api.getZr();
            this._tooltipContent.hide();
            zr.off(&apos;click&apos;, this._tryShow);
            zr.off(&apos;mousemove&apos;, this._mousemove);
            zr.off(&apos;mouseout&apos;, this._hide);
            zr.off(&apos;globalout&apos;, this._hide);
            api.off(&apos;showTip&apos;, this._manuallyShowTip);
            api.off(&apos;hideTip&apos;, this._manuallyHideTip);
        }
    });
});
define(&apos;echarts/coord/polar/Polar&apos;, [&apos;require&apos;, &apos;./RadiusAxis&apos;, &apos;./AngleAxis&apos;], function (require) {
    &apos;use strict&apos;;
    var RadiusAxis = require(&apos;./RadiusAxis&apos;);
    var AngleAxis = require(&apos;./AngleAxis&apos;);
    /**
     * @alias {module:echarts/coord/polar/Polar}
     * @constructor
     * @param {string} name
     */
    var Polar = function (name) {
        /**
         * @type {string}
         */
        this.name = name || &apos;&apos;;
        /**
         * x of polar center
         * @type {number}
         */
        this.cx = 0;
        /**
         * y of polar center
         * @type {number}
         */
        this.cy = 0;
        /**
         * @type {module:echarts/coord/polar/RadiusAxis}
         * @private
         */
        this._radiusAxis = new RadiusAxis();
        /**
         * @type {module:echarts/coord/polar/AngleAxis}
         * @private
         */
        this._angleAxis = new AngleAxis();
    };
    Polar.prototype = {
        constructor: Polar,
        type: &apos;polar&apos;,
        dimensions: [
            &apos;radius&apos;,
            &apos;angle&apos;
        ],
        containPoint: function (point) {
            var coord = this.pointToCoord(point);
            return this._radiusAxis.contain(coord[0]) &amp;&amp; this._angleAxis.contain(coord[1]);
        },
        containData: function (data) {
            return this._radiusAxis.containData(data[0]) &amp;&amp; this._angleAxis.containData(data[1]);
        },
        getAxis: function (axisType) {
            return this[&apos;_&apos; + axisType + &apos;Axis&apos;];
        },
        getAxesByScale: function (scaleType) {
            var axes = [];
            var angleAxis = this._angleAxis;
            var radiusAxis = this._radiusAxis;
            angleAxis.scale.type === scaleType &amp;&amp; axes.push(angleAxis);
            radiusAxis.scale.type === scaleType &amp;&amp; axes.push(radiusAxis);
            return axes;
        },
        getAngleAxis: function () {
            return this._angleAxis;
        },
        getRadiusAxis: function () {
            return this._radiusAxis;
        },
        getOtherAxis: function (axis) {
            var angleAxis = this._angleAxis;
            return axis === angleAxis ? this._radiusAxis : angleAxis;
        },
        getBaseAxis: function () {
            return this.getAxesByScale(&apos;ordinal&apos;)[0] || this.getAxesByScale(&apos;time&apos;)[0] || this.getAngleAxis();
        },
        dataToPoints: function (data) {
            return data.mapArray(this.dimensions, function (radius, angle) {
                return this.dataToPoint([
                    radius,
                    angle
                ]);
            }, this);
        },
        dataToPoint: function (data, clamp) {
            return this.coordToPoint([
                this._radiusAxis.dataToRadius(data[0], clamp),
                this._angleAxis.dataToAngle(data[1], clamp)
            ]);
        },
        pointToData: function (point, clamp) {
            var coord = this.pointToCoord(point);
            return [
                this._radiusAxis.radiusToData(coord[0], clamp),
                this._angleAxis.angleToData(coord[1], clamp)
            ];
        },
        pointToCoord: function (point) {
            var dx = point[0] - this.cx;
            var dy = point[1] - this.cy;
            var angleAxis = this.getAngleAxis();
            var extent = angleAxis.getExtent();
            var minAngle = Math.min(extent[0], extent[1]);
            var maxAngle = Math.max(extent[0], extent[1]);
            // Fix fixed extent in polarCreator
            // FIXME
            angleAxis.inverse ? minAngle = maxAngle - 360 : maxAngle = minAngle + 360;
            var radius = Math.sqrt(dx * dx + dy * dy);
            dx /= radius;
            dy /= radius;
            var radian = Math.atan2(-dy, dx) / Math.PI * 180;
            // move to angleExtent
            var dir = radian &lt; minAngle ? 1 : -1;
            while (radian &lt; minAngle || radian &gt; maxAngle) {
                radian += dir * 360;
            }
            return [
                radius,
                radian
            ];
        },
        coordToPoint: function (coord) {
            var radius = coord[0];
            var radian = coord[1] / 180 * Math.PI;
            var x = Math.cos(radian) * radius + this.cx;
            // Inverse the y
            var y = -Math.sin(radian) * radius + this.cy;
            return [
                x,
                y
            ];
        }
    };
    return Polar;
});
define(&apos;echarts/coord/polar/PolarModel&apos;, [&apos;require&apos;, &apos;./AxisModel&apos;, &apos;../../echarts&apos;], function (require) {
    &apos;use strict&apos;;
    require(&apos;./AxisModel&apos;);
    require(&apos;../../echarts&apos;).extendComponentModel({
        type: &apos;polar&apos;,
        dependencies: [
            &apos;polarAxis&apos;,
            &apos;angleAxis&apos;
        ],
        coordinateSystem: null,
        findAxisModel: function (axisType) {
            var angleAxisModel;
            var ecModel = this.ecModel;
            ecModel.eachComponent(axisType, function (axisModel) {
                if (ecModel.getComponent(&apos;polar&apos;, axisModel.getShallow(&apos;polarIndex&apos;)) === this) {
                    angleAxisModel = axisModel;
                }
            }, this);
            return angleAxisModel;
        },
        defaultOption: {
            zlevel: 0,
            z: 0,
            center: [
                &apos;50%&apos;,
                &apos;50%&apos;
            ],
            radius: &apos;80%&apos;
        }
    });
});
define(&apos;echarts/coord/axisHelper&apos;, [&apos;require&apos;, &apos;../scale/Ordinal&apos;, &apos;../scale/Interval&apos;, &apos;../scale/Time&apos;, &apos;../scale/Log&apos;, &apos;../scale/Scale&apos;, &apos;../util/number&apos;, &apos;zrender/core/util&apos;, &apos;zrender/contain/text&apos;], function (require) {
    var OrdinalScale = require(&apos;../scale/Ordinal&apos;);
    var IntervalScale = require(&apos;../scale/Interval&apos;);
    require(&apos;../scale/Time&apos;);
    require(&apos;../scale/Log&apos;);
    var Scale = require(&apos;../scale/Scale&apos;);
    var numberUtil = require(&apos;../util/number&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var textContain = require(&apos;zrender/contain/text&apos;);
    var axisHelper = {};
    /**
     * Get axis scale extent before niced.
     */
    axisHelper.getScaleExtent = function (axis, model) {
        var scale = axis.scale;
        var originalExtent = scale.getExtent();
        var span = originalExtent[1] - originalExtent[0];
        if (scale.type === &apos;ordinal&apos;) {
            // If series has no data, scale extent may be wrong
            if (!isFinite(span)) {
                return [
                    0,
                    0
                ];
            } else {
                return originalExtent;
            }
        }
        var min = model.getMin ? model.getMin() : model.get(&apos;min&apos;);
        var max = model.getMax ? model.getMax() : model.get(&apos;max&apos;);
        var crossZero = model.getNeedCrossZero ? model.getNeedCrossZero() : !model.get(&apos;scale&apos;);
        var boundaryGap = model.get(&apos;boundaryGap&apos;);
        if (!zrUtil.isArray(boundaryGap)) {
            boundaryGap = [
                boundaryGap || 0,
                boundaryGap || 0
            ];
        }
        boundaryGap[0] = numberUtil.parsePercent(boundaryGap[0], 1);
        boundaryGap[1] = numberUtil.parsePercent(boundaryGap[1], 1);
        var fixMin = true;
        var fixMax = true;
        // Add boundary gap
        if (min == null) {
            min = originalExtent[0] - boundaryGap[0] * span;
            fixMin = false;
        }
        if (max == null) {
            max = originalExtent[1] + boundaryGap[1] * span;
            fixMax = false;
        }
        if (min === &apos;dataMin&apos;) {
            min = originalExtent[0];
        }
        if (max === &apos;dataMax&apos;) {
            max = originalExtent[1];
        }
        // Evaluate if axis needs cross zero
        if (crossZero) {
            // Axis is over zero and min is not set
            if (min &gt; 0 &amp;&amp; max &gt; 0 &amp;&amp; !fixMin) {
                min = 0;
            }
            // Axis is under zero and max is not set
            if (min &lt; 0 &amp;&amp; max &lt; 0 &amp;&amp; !fixMax) {
                max = 0;
            }
        }
        return [
            min,
            max
        ];
    };
    axisHelper.niceScaleExtent = function (axis, model) {
        var scale = axis.scale;
        var extent = axisHelper.getScaleExtent(axis, model);
        var fixMin = (model.getMin ? model.getMin() : model.get(&apos;min&apos;)) != null;
        var fixMax = (model.getMax ? model.getMax() : model.get(&apos;max&apos;)) != null;
        var splitNumber = model.get(&apos;splitNumber&apos;);
        scale.setExtent(extent[0], extent[1]);
        scale.niceExtent(splitNumber, fixMin, fixMax);
        // Use minInterval to constraint the calculated interval.
        // If calculated interval is less than minInterval. increase the interval quantity until
        // it is larger than minInterval.
        // For example:
        //  minInterval is 1, calculated interval is 0.2, so increase it to be 1. In this way we can get
        //  an integer axis.
        var minInterval = model.get(&apos;minInterval&apos;);
        if (isFinite(minInterval) &amp;&amp; !fixMin &amp;&amp; !fixMax &amp;&amp; scale.type === &apos;interval&apos;) {
            var interval = scale.getInterval();
            var intervalScale = Math.max(Math.abs(interval), minInterval) / interval;
            // while (interval &lt; minInterval) {
            //     var quantity = numberUtil.quantity(interval);
            //     interval = quantity * 10;
            //     scaleQuantity *= 10;
            // }
            extent = scale.getExtent();
            scale.setExtent(intervalScale * extent[0], extent[1] * intervalScale);
            scale.niceExtent(splitNumber);
        }
        // If some one specified the min, max. And the default calculated interval
        // is not good enough. He can specify the interval. It is often appeared
        // in angle axis with angle 0 - 360. Interval calculated in interval scale is hard
        // to be 60.
        // FIXME
        var interval = model.get(&apos;interval&apos;);
        if (interval != null) {
            scale.setInterval &amp;&amp; scale.setInterval(interval);
        }
    };
    /**
     * @param {module:echarts/model/Model} model
     * @param {string} [axisType] Default retrieve from model.type
     * @return {module:echarts/scale/*}
     */
    axisHelper.createScaleByModel = function (model, axisType) {
        axisType = axisType || model.get(&apos;type&apos;);
        if (axisType) {
            switch (axisType) {
            // Buildin scale
            case &apos;category&apos;:
                return new OrdinalScale(model.getCategories(), [
                    Infinity,
                    -Infinity
                ]);
            case &apos;value&apos;:
                return new IntervalScale();
            // Extended scale, like time and log
            default:
                return (Scale.getClass(axisType) || IntervalScale).create(model);
            }
        }
    };
    /**
     * Check if the axis corss 0
     */
    axisHelper.ifAxisCrossZero = function (axis) {
        var dataExtent = axis.scale.getExtent();
        var min = dataExtent[0];
        var max = dataExtent[1];
        return !(min &gt; 0 &amp;&amp; max &gt; 0 || min &lt; 0 &amp;&amp; max &lt; 0);
    };
    /**
     * @param {Array.<number>} tickCoords In axis self coordinate.
     * @param {Array.<string>} labels
     * @param {string} font
     * @param {boolean} isAxisHorizontal
     * @return {number}
     */
    axisHelper.getAxisLabelInterval = function (tickCoords, labels, font, isAxisHorizontal) {
        // FIXME
        // &#x4E0D;&#x540C;&#x89D2;&#x7684;axis&#x548C;label&#xFF0C;&#x4E0D;&#x53EA;&#x662F;horizontal&#x548C;vertical.
        var textSpaceTakenRect;
        var autoLabelInterval = 0;
        var accumulatedLabelInterval = 0;
        var step = 1;
        if (labels.length &gt; 40) {
            // Simple optimization for large amount of labels
            step = Math.floor(labels.length / 40);
        }
        for (var i = 0; i &lt; tickCoords.length; i += step) {
            var tickCoord = tickCoords[i];
            var rect = textContain.getBoundingRect(labels[i], font, &apos;center&apos;, &apos;top&apos;);
            rect[isAxisHorizontal ? &apos;x&apos; : &apos;y&apos;] += tickCoord;
            // FIXME Magic number 1.5
            rect[isAxisHorizontal ? &apos;width&apos; : &apos;height&apos;] *= 1.3;
            if (!textSpaceTakenRect) {
                textSpaceTakenRect = rect.clone();
            }    // There is no space for current label;
            else if (textSpaceTakenRect.intersect(rect)) {
                accumulatedLabelInterval++;
                autoLabelInterval = Math.max(autoLabelInterval, accumulatedLabelInterval);
            } else {
                textSpaceTakenRect.union(rect);
                // Reset
                accumulatedLabelInterval = 0;
            }
        }
        if (autoLabelInterval === 0 &amp;&amp; step &gt; 1) {
            return step;
        }
        return (autoLabelInterval + 1) * step - 1;
    };
    /**
     * @param {Object} axis
     * @param {Function} labelFormatter
     * @return {Array.<string>}
     */
    axisHelper.getFormattedLabels = function (axis, labelFormatter) {
        var scale = axis.scale;
        var labels = scale.getTicksLabels();
        var ticks = scale.getTicks();
        if (typeof labelFormatter === &apos;string&apos;) {
            labelFormatter = function (tpl) {
                return function (val) {
                    return tpl.replace(&apos;{value}&apos;, val);
                };
            }(labelFormatter);
            return zrUtil.map(labels, labelFormatter);
        } else if (typeof labelFormatter === &apos;function&apos;) {
            return zrUtil.map(ticks, function (tick, idx) {
                return labelFormatter(axis.type === &apos;category&apos; ? scale.getLabel(tick) : tick, idx);
            }, this);
        } else {
            return labels;
        }
    };
    return axisHelper;
});
define(&apos;echarts/model/mixin/lineStyle&apos;, [&apos;require&apos;, &apos;./makeStyleMapper&apos;], function (require) {
    var getLineStyle = require(&apos;./makeStyleMapper&apos;)([
            [
                &apos;lineWidth&apos;,
                &apos;width&apos;
            ],
            [
                &apos;stroke&apos;,
                &apos;color&apos;
            ],
            [&apos;opacity&apos;],
            [&apos;shadowBlur&apos;],
            [&apos;shadowOffsetX&apos;],
            [&apos;shadowOffsetY&apos;],
            [&apos;shadowColor&apos;]
        ]);
    return {
        getLineStyle: function (excludes) {
            var style = getLineStyle.call(this, excludes);
            var lineDash = this.getLineDash();
            lineDash &amp;&amp; (style.lineDash = lineDash);
            return style;
        },
        getLineDash: function () {
            var lineType = this.get(&apos;type&apos;);
            return lineType === &apos;solid&apos; || lineType == null ? null : lineType === &apos;dashed&apos; ? [
                5,
                5
            ] : [
                1,
                1
            ];
        }
    };
});
define(&apos;echarts/scale/Scale&apos;, [&apos;require&apos;, &apos;../util/clazz&apos;], function (require) {
    var clazzUtil = require(&apos;../util/clazz&apos;);
    function Scale() {
        /**
         * Extent
         * @type {Array.<number>}
         * @protected
         */
        this._extent = [
            Infinity,
            -Infinity
        ];
        /**
         * Step is calculated in adjustExtent
         * @type {Array.<number>}
         * @protected
         */
        this._interval = 0;
        this.init &amp;&amp; this.init.apply(this, arguments);
    }
    var scaleProto = Scale.prototype;
    /**
     * Parse input val to valid inner number.
     * @param {*} val
     * @return {number}
     */
    scaleProto.parse = function (val) {
        // Notice: This would be a trap here, If the implementation
        // of this method depends on extent, and this method is used
        // before extent set (like in dataZoom), it would be wrong.
        // Nevertheless, parse does not depend on extent generally.
        return val;
    };
    scaleProto.contain = function (val) {
        var extent = this._extent;
        return val &gt;= extent[0] &amp;&amp; val <= 0="" extent[1];="" };="" **="" *="" normalize="" value="" to="" linear="" [0,="" 1],="" return="" 0.5="" if="" extent="" span="" is="" @param="" {number}="" val="" @return="" scaleproto.normalize="function" (val)="" {="" var="" (extent[1]="==" extent[0])="" 0.5;="" }="" (val="" -="" extent[0]);="" scale="" normalized="" scaleproto.scale="function" +="" extent[0];="" set="" from="" data="" {array.<number="">} other
     */
    scaleProto.unionExtent = function (other) {
        var extent = this._extent;
        other[0] &lt; extent[0] &amp;&amp; (extent[0] = other[0]);
        other[1] &gt; extent[1] &amp;&amp; (extent[1] = other[1]);    // not setExtent because in log axis it may transformed to power
                                                           // this.setExtent(extent[0], extent[1]);
    };
    /**
     * Get extent
     * @return {Array.<number>}
     */
    scaleProto.getExtent = function () {
        return this._extent.slice();
    };
    /**
     * Set extent
     * @param {number} start
     * @param {number} end
     */
    scaleProto.setExtent = function (start, end) {
        var thisExtent = this._extent;
        if (!isNaN(start)) {
            thisExtent[0] = start;
        }
        if (!isNaN(end)) {
            thisExtent[1] = end;
        }
    };
    /**
     * @return {Array.<string>}
     */
    scaleProto.getTicksLabels = function () {
        var labels = [];
        var ticks = this.getTicks();
        for (var i = 0; i &lt; ticks.length; i++) {
            labels.push(this.getLabel(ticks[i]));
        }
        return labels;
    };
    clazzUtil.enableClassExtend(Scale);
    clazzUtil.enableClassManagement(Scale, { registerWhenExtend: true });
    return Scale;
});
define(&apos;echarts/model/mixin/textStyle&apos;, [&apos;require&apos;, &apos;zrender/contain/text&apos;], function (require) {
    var textContain = require(&apos;zrender/contain/text&apos;);
    function getShallow(model, path) {
        return model &amp;&amp; model.getShallow(path);
    }
    return {
        getTextColor: function () {
            var ecModel = this.ecModel;
            return this.getShallow(&apos;color&apos;) || ecModel &amp;&amp; ecModel.get(&apos;textStyle.color&apos;);
        },
        getFont: function () {
            var ecModel = this.ecModel;
            var gTextStyleModel = ecModel &amp;&amp; ecModel.getModel(&apos;textStyle&apos;);
            return [
                this.getShallow(&apos;fontStyle&apos;) || getShallow(gTextStyleModel, &apos;fontStyle&apos;),
                this.getShallow(&apos;fontWeight&apos;) || getShallow(gTextStyleModel, &apos;fontWeight&apos;),
                (this.getShallow(&apos;fontSize&apos;) || getShallow(gTextStyleModel, &apos;fontSize&apos;) || 12) + &apos;px&apos;,
                this.getShallow(&apos;fontFamily&apos;) || getShallow(gTextStyleModel, &apos;fontFamily&apos;) || &apos;sans-serif&apos;
            ].join(&apos; &apos;);
        },
        getTextRect: function (text) {
            var textStyle = this.get(&apos;textStyle&apos;) || {};
            return textContain.getBoundingRect(text, this.getFont(), textStyle.align, textStyle.baseline);
        },
        truncateText: function (text, containerWidth, ellipsis, options) {
            return textContain.truncateText(text, containerWidth, this.getFont(), ellipsis, options);
        }
    };
});
define(&apos;echarts/util/model&apos;, [&apos;require&apos;, &apos;./format&apos;, &apos;./number&apos;, &apos;../model/Model&apos;, &apos;zrender/core/util&apos;], function (require) {
    var formatUtil = require(&apos;./format&apos;);
    var nubmerUtil = require(&apos;./number&apos;);
    var Model = require(&apos;../model/Model&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var AXIS_DIMS = [
            &apos;x&apos;,
            &apos;y&apos;,
            &apos;z&apos;,
            &apos;radius&apos;,
            &apos;angle&apos;
        ];
    var modelUtil = {};
    /**
     * Create &quot;each&quot; method to iterate names.
     *
     * @pubilc
     * @param  {Array.<string>} names
     * @param  {Array.<string>=} attrs
     * @return {Function}
     */
    modelUtil.createNameEach = function (names, attrs) {
        names = names.slice();
        var capitalNames = zrUtil.map(names, modelUtil.capitalFirst);
        attrs = (attrs || []).slice();
        var capitalAttrs = zrUtil.map(attrs, modelUtil.capitalFirst);
        return function (callback, context) {
            zrUtil.each(names, function (name, index) {
                var nameObj = {
                        name: name,
                        capital: capitalNames[index]
                    };
                for (var j = 0; j &lt; attrs.length; j++) {
                    nameObj[attrs[j]] = name + capitalAttrs[j];
                }
                callback.call(context, nameObj);
            });
        };
    };
    /**
     * @public
     */
    modelUtil.capitalFirst = function (str) {
        return str ? str.charAt(0).toUpperCase() + str.substr(1) : str;
    };
    /**
     * Iterate each dimension name.
     *
     * @public
     * @param {Function} callback The parameter is like:
     *                            {
     *                                name: &apos;angle&apos;,
     *                                capital: &apos;Angle&apos;,
     *                                axis: &apos;angleAxis&apos;,
     *                                axisIndex: &apos;angleAixs&apos;,
     *                                index: &apos;angleIndex&apos;
     *                            }
     * @param {Object} context
     */
    modelUtil.eachAxisDim = modelUtil.createNameEach(AXIS_DIMS, [
        &apos;axisIndex&apos;,
        &apos;axis&apos;,
        &apos;index&apos;
    ]);
    /**
     * If value is not array, then translate it to array.
     * @param  {*} value
     * @return {Array} [value] or value
     */
    modelUtil.normalizeToArray = function (value) {
        return value instanceof Array ? value : value == null ? [] : [value];
    };
    /**
     * If tow dataZoomModels has the same axis controlled, we say that they are &apos;linked&apos;.
     * dataZoomModels and &apos;links&apos; make up one or more graphics.
     * This function finds the graphic where the source dataZoomModel is in.
     *
     * @public
     * @param {Function} forEachNode Node iterator.
     * @param {Function} forEachEdgeType edgeType iterator
     * @param {Function} edgeIdGetter Giving node and edgeType, return an array of edge id.
     * @return {Function} Input: sourceNode, Output: Like {nodes: [], dims: {}}
     */
    modelUtil.createLinkedNodesFinder = function (forEachNode, forEachEdgeType, edgeIdGetter) {
        return function (sourceNode) {
            var result = {
                    nodes: [],
                    records: {}
                };
            forEachEdgeType(function (edgeType) {
                result.records[edgeType.name] = {};
            });
            if (!sourceNode) {
                return result;
            }
            absorb(sourceNode, result);
            var existsLink;
            do {
                existsLink = false;
                forEachNode(processSingleNode);
            } while (existsLink);
            function processSingleNode(node) {
                if (!isNodeAbsorded(node, result) &amp;&amp; isLinked(node, result)) {
                    absorb(node, result);
                    existsLink = true;
                }
            }
            return result;
        };
        function isNodeAbsorded(node, result) {
            return zrUtil.indexOf(result.nodes, node) &gt;= 0;
        }
        function isLinked(node, result) {
            var hasLink = false;
            forEachEdgeType(function (edgeType) {
                zrUtil.each(edgeIdGetter(node, edgeType) || [], function (edgeId) {
                    result.records[edgeType.name][edgeId] &amp;&amp; (hasLink = true);
                });
            });
            return hasLink;
        }
        function absorb(node, result) {
            result.nodes.push(node);
            forEachEdgeType(function (edgeType) {
                zrUtil.each(edgeIdGetter(node, edgeType) || [], function (edgeId) {
                    result.records[edgeType.name][edgeId] = true;
                });
            });
        }
    };
    /**
     * Sync default option between normal and emphasis like `position` and `show`
     * In case some one will write code like
     *     label: {
     *         normal: {
     *             show: false,
     *             position: &apos;outside&apos;,
     *             textStyle: {
     *                 fontSize: 18
     *             }
     *         },
     *         emphasis: {
     *             show: true
     *         }
     *     }
     * @param {Object} opt
     * @param {Array.<string>} subOpts
     */
    modelUtil.defaultEmphasis = function (opt, subOpts) {
        if (opt) {
            var emphasisOpt = opt.emphasis = opt.emphasis || {};
            var normalOpt = opt.normal = opt.normal || {};
            // Default emphasis option from normal
            zrUtil.each(subOpts, function (subOptName) {
                var val = zrUtil.retrieve(emphasisOpt[subOptName], normalOpt[subOptName]);
                if (val != null) {
                    emphasisOpt[subOptName] = val;
                }
            });
        }
    };
    modelUtil.LABEL_OPTIONS = [
        &apos;position&apos;,
        &apos;show&apos;,
        &apos;textStyle&apos;,
        &apos;distance&apos;,
        &apos;formatter&apos;
    ];
    /**
     * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
     * This helper method retieves value from data.
     * @param {string|number|Date|Array|Object} dataItem
     * @return {number|string|Date|Array.<number|string|date>}
     */
    modelUtil.getDataItemValue = function (dataItem) {
        // Performance sensitive.
        return dataItem &amp;&amp; (dataItem.value == null ? dataItem : dataItem.value);
    };
    /**
     * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
     * This helper method determine if dataItem has extra option besides value
     * @param {string|number|Date|Array|Object} dataItem
     */
    modelUtil.isDataItemOption = function (dataItem) {
        return zrUtil.isObject(dataItem) &amp;&amp; !(dataItem instanceof Array);    // // markLine data can be array
                                                                             // &amp;&amp; !(dataItem[0] &amp;&amp; zrUtil.isObject(dataItem[0]) &amp;&amp; !(dataItem[0] instanceof Array));
    };
    /**
     * This helper method convert value in data.
     * @param {string|number|Date} value
     * @param {Object|string} [dimInfo] If string (like &apos;x&apos;), dimType defaults &apos;number&apos;.
     */
    modelUtil.converDataValue = function (value, dimInfo) {
        // Performance sensitive.
        var dimType = dimInfo &amp;&amp; dimInfo.type;
        if (dimType === &apos;ordinal&apos;) {
            return value;
        }
        if (dimType === &apos;time&apos; &amp;&amp; !isFinite(value) &amp;&amp; value != null &amp;&amp; value !== &apos;-&apos;) {
            value = +nubmerUtil.parseDate(value);
        }
        // dimType defaults &apos;number&apos;.
        // If dimType is not ordinal and value is null or undefined or NaN or &apos;-&apos;,
        // parse to NaN.
        return value == null || value === &apos;&apos; ? NaN : +value;    // If string (like &apos;-&apos;), using &apos;+&apos; parse to NaN
    };
    /**
     * Create a model proxy to be used in tooltip for edge data, markLine data, markPoint data.
     * @param {module:echarts/data/List} data
     * @param {Object} opt
     * @param {string} [opt.seriesIndex]
     * @param {Object} [opt.name]
     * @param {Object} [opt.mainType]
     * @param {Object} [opt.subType]
     */
    modelUtil.createDataFormatModel = function (data, opt) {
        var model = new Model();
        zrUtil.mixin(model, modelUtil.dataFormatMixin);
        model.seriesIndex = opt.seriesIndex;
        model.name = opt.name || &apos;&apos;;
        model.mainType = opt.mainType;
        model.subType = opt.subType;
        model.getData = function () {
            return data;
        };
        return model;
    };
    // PENDING A little ugly
    modelUtil.dataFormatMixin = {
        getDataParams: function (dataIndex, dataType) {
            var data = this.getData(dataType);
            var seriesIndex = this.seriesIndex;
            var seriesName = this.name;
            var rawValue = this.getRawValue(dataIndex, dataType);
            var rawDataIndex = data.getRawIndex(dataIndex);
            var name = data.getName(dataIndex, true);
            var itemOpt = data.getRawDataItem(dataIndex);
            return {
                componentType: this.mainType,
                componentSubType: this.subType,
                seriesType: this.mainType === &apos;series&apos; ? this.subType : null,
                seriesIndex: seriesIndex,
                seriesName: seriesName,
                name: name,
                dataIndex: rawDataIndex,
                data: itemOpt,
                dataType: dataType,
                value: rawValue,
                color: data.getItemVisual(dataIndex, &apos;color&apos;),
                $vars: [
                    &apos;seriesName&apos;,
                    &apos;name&apos;,
                    &apos;value&apos;
                ]
            };
        },
        getFormattedLabel: function (dataIndex, status, dataType, dimIndex) {
            status = status || &apos;normal&apos;;
            var data = this.getData(dataType);
            var itemModel = data.getItemModel(dataIndex);
            var params = this.getDataParams(dataIndex, dataType);
            if (dimIndex != null &amp;&amp; params.value instanceof Array) {
                params.value = params.value[dimIndex];
            }
            var formatter = itemModel.get([
                    &apos;label&apos;,
                    status,
                    &apos;formatter&apos;
                ]);
            if (typeof formatter === &apos;function&apos;) {
                params.status = status;
                return formatter(params);
            } else if (typeof formatter === &apos;string&apos;) {
                return formatUtil.formatTpl(formatter, params);
            }
        },
        getRawValue: function (idx, dataType) {
            var data = this.getData(dataType);
            var dataItem = data.getRawDataItem(idx);
            if (dataItem != null) {
                return zrUtil.isObject(dataItem) &amp;&amp; !(dataItem instanceof Array) ? dataItem.value : dataItem;
            }
        },
        formatTooltip: zrUtil.noop
    };
    /**
     * Mapping to exists for merge.
     *
     * @public
     * @param {Array.<object>|Array.<module:echarts model="" component="">} exists
     * @param {Object|Array.<object>} newCptOptions
     * @return {Array.<object>} Result, like [{exist: ..., option: ...}, {}],
     *                          which order is the same as exists.
     */
    modelUtil.mappingToExists = function (exists, newCptOptions) {
        // Mapping by the order by original option (but not order of
        // new option) in merge mode. Because we should ensure
        // some specified index (like xAxisIndex) is consistent with
        // original option, which is easy to understand, espatially in
        // media query. And in most case, merge option is used to
        // update partial option but not be expected to change order.
        newCptOptions = (newCptOptions || []).slice();
        var result = zrUtil.map(exists || [], function (obj, index) {
                return { exist: obj };
            });
        // Mapping by id or name if specified.
        zrUtil.each(newCptOptions, function (cptOption, index) {
            if (!zrUtil.isObject(cptOption)) {
                return;
            }
            for (var i = 0; i &lt; result.length; i++) {
                var exist = result[i].exist;
                if (!result[i].option &amp;&amp; (cptOption.id != null &amp;&amp; exist.id === cptOption.id + &apos;&apos; || cptOption.name != null &amp;&amp; !modelUtil.isIdInner(cptOption) &amp;&amp; !modelUtil.isIdInner(exist) &amp;&amp; exist.name === cptOption.name + &apos;&apos;)) {
                    result[i].option = cptOption;
                    newCptOptions[index] = null;
                    break;
                }
            }
        });
        // Otherwise mapping by index.
        zrUtil.each(newCptOptions, function (cptOption, index) {
            if (!zrUtil.isObject(cptOption)) {
                return;
            }
            var i = 0;
            for (; i &lt; result.length; i++) {
                var exist = result[i].exist;
                if (!result[i].option &amp;&amp; !modelUtil.isIdInner(exist) &amp;&amp; cptOption.id == null) {
                    result[i].option = cptOption;
                    break;
                }
            }
            if (i &gt;= result.length) {
                result.push({ option: cptOption });
            }
        });
        return result;
    };
    /**
     * @public
     * @param {Object} cptOption
     * @return {boolean}
     */
    modelUtil.isIdInner = function (cptOption) {
        return zrUtil.isObject(cptOption) &amp;&amp; cptOption.id &amp;&amp; (cptOption.id + &apos;&apos;).indexOf(&apos; _ec_ &apos;) === 0;
    };
    /**
     * A helper for removing duplicate items between batchA and batchB,
     * and in themselves, and categorize by series.
     *
     * @param {Array.<object>} batchA Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...]
     * @param {Array.<object>} batchB Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...]
     * @return {Array.<array.<object>, Array.<object>&gt;} result: [resultBatchA, resultBatchB]
     */
    modelUtil.compressBatches = function (batchA, batchB) {
        var mapA = {};
        var mapB = {};
        makeMap(batchA || [], mapA);
        makeMap(batchB || [], mapB, mapA);
        return [
            mapToArray(mapA),
            mapToArray(mapB)
        ];
        function makeMap(sourceBatch, map, otherMap) {
            for (var i = 0, len = sourceBatch.length; i &lt; len; i++) {
                var seriesId = sourceBatch[i].seriesId;
                var dataIndices = modelUtil.normalizeToArray(sourceBatch[i].dataIndex);
                var otherDataIndices = otherMap &amp;&amp; otherMap[seriesId];
                for (var j = 0, lenj = dataIndices.length; j &lt; lenj; j++) {
                    var dataIndex = dataIndices[j];
                    if (otherDataIndices &amp;&amp; otherDataIndices[dataIndex]) {
                        otherDataIndices[dataIndex] = null;
                    } else {
                        (map[seriesId] || (map[seriesId] = {}))[dataIndex] = 1;
                    }
                }
            }
        }
        function mapToArray(map, isData) {
            var result = [];
            for (var i in map) {
                if (map.hasOwnProperty(i) &amp;&amp; map[i] != null) {
                    if (isData) {
                        result.push(+i);
                    } else {
                        var dataIndices = mapToArray(map[i], true);
                        dataIndices.length &amp;&amp; result.push({
                            seriesId: i,
                            dataIndex: dataIndices
                        });
                    }
                }
            }
            return result;
        }
    };
    return modelUtil;
});
define(&apos;echarts/model/globalDefault&apos;, [], function () {
    var platform = &apos;&apos;;
    // Navigator not exists in node
    if (typeof navigator !== &apos;undefined&apos;) {
        platform = navigator.platform || &apos;&apos;;
    }
    return {
        color: [
            &apos;#c23531&apos;,
            &apos;#2f4554&apos;,
            &apos;#61a0a8&apos;,
            &apos;#d48265&apos;,
            &apos;#91c7ae&apos;,
            &apos;#749f83&apos;,
            &apos;#ca8622&apos;,
            &apos;#bda29a&apos;,
            &apos;#6e7074&apos;,
            &apos;#546570&apos;,
            &apos;#c4ccd3&apos;
        ],
        grid: {},
        textStyle: {
            fontFamily: platform.match(/^Win/) ? &apos;Microsoft YaHei&apos; : &apos;sans-serif&apos;,
            fontSize: 12,
            fontStyle: &apos;normal&apos;,
            fontWeight: &apos;normal&apos;
        },
        blendMode: null,
        animation: true,
        animationDuration: 1000,
        animationDurationUpdate: 300,
        animationEasing: &apos;exponentialOut&apos;,
        animationEasingUpdate: &apos;cubicOut&apos;,
        animationThreshold: 2000,
        progressiveThreshold: 3000,
        progressive: 400,
        hoverLayerThreshold: 3000
    };
});
define(&apos;echarts/model/mixin/colorPalette&apos;, [], function () {
    return {
        clearColorPalette: function () {
            this._colorIdx = 0;
            this._colorNameMap = {};
        },
        getColorFromPalette: function (name, scope) {
            scope = scope || this;
            var colorIdx = scope._colorIdx || 0;
            var colorNameMap = scope._colorNameMap || (scope._colorNameMap = {});
            if (colorNameMap[name]) {
                return colorNameMap[name];
            }
            var colorPalette = this.get(&apos;color&apos;, true) || [];
            if (!colorPalette.length) {
                return;
            }
            var color = colorPalette[colorIdx];
            if (name) {
                colorNameMap[name] = color;
            }
            scope._colorIdx = (colorIdx + 1) % colorPalette.length;
            return color;
        }
    };
});
define(&apos;echarts/util/clazz&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var clazz = {};
    var TYPE_DELIMITER = &apos;.&apos;;
    var IS_CONTAINER = &apos;___EC__COMPONENT__CONTAINER___&apos;;
    /**
     * @public
     */
    var parseClassType = clazz.parseClassType = function (componentType) {
            var ret = {
                    main: &apos;&apos;,
                    sub: &apos;&apos;
                };
            if (componentType) {
                componentType = componentType.split(TYPE_DELIMITER);
                ret.main = componentType[0] || &apos;&apos;;
                ret.sub = componentType[1] || &apos;&apos;;
            }
            return ret;
        };
    /**
     * @public
     */
    clazz.enableClassExtend = function (RootClass) {
        RootClass.$constructor = RootClass;
        RootClass.extend = function (proto) {
            var superClass = this;
            var ExtendedClass = function () {
                if (!proto.$constructor) {
                    superClass.apply(this, arguments);
                } else {
                    proto.$constructor.apply(this, arguments);
                }
            };
            zrUtil.extend(ExtendedClass.prototype, proto);
            ExtendedClass.extend = this.extend;
            ExtendedClass.superCall = superCall;
            ExtendedClass.superApply = superApply;
            zrUtil.inherits(ExtendedClass, this);
            ExtendedClass.superClass = superClass;
            return ExtendedClass;
        };
    };
    // superCall should have class info, which can not be fetch from &apos;this&apos;.
    // Consider this case:
    // class A has method f,
    // class B inherits class A, overrides method f, f call superApply(&apos;f&apos;),
    // class C inherits class B, do not overrides method f,
    // then when method of class C is called, dead loop occured.
    function superCall(context, methodName) {
        var args = zrUtil.slice(arguments, 2);
        return this.superClass.prototype[methodName].apply(context, args);
    }
    function superApply(context, methodName, args) {
        return this.superClass.prototype[methodName].apply(context, args);
    }
    /**
     * @param {Object} entity
     * @param {Object} options
     * @param {boolean} [options.registerWhenExtend]
     * @public
     */
    clazz.enableClassManagement = function (entity, options) {
        options = options || {};
        /**
         * Component model classes
         * key: componentType,
         * value:
         *     componentClass, when componentType is &apos;xxx&apos;
         *     or Object.<subkey, componentclass="">, when componentType is &apos;xxx.yy&apos;
         * @type {Object}
         */
        var storage = {};
        entity.registerClass = function (Clazz, componentType) {
            if (componentType) {
                componentType = parseClassType(componentType);
                if (!componentType.sub) {
                    if (true) {
                        if (storage[componentType.main]) {
                            console.warn(componentType.main + &apos; exists.&apos;);
                        }
                    }
                    storage[componentType.main] = Clazz;
                } else if (componentType.sub !== IS_CONTAINER) {
                    var container = makeContainer(componentType);
                    container[componentType.sub] = Clazz;
                }
            }
            return Clazz;
        };
        entity.getClass = function (componentTypeMain, subType, throwWhenNotFound) {
            var Clazz = storage[componentTypeMain];
            if (Clazz &amp;&amp; Clazz[IS_CONTAINER]) {
                Clazz = subType ? Clazz[subType] : null;
            }
            if (throwWhenNotFound &amp;&amp; !Clazz) {
                throw new Error(&apos;Component &apos; + componentTypeMain + &apos;.&apos; + (subType || &apos;&apos;) + &apos; not exists. Load it first.&apos;);
            }
            return Clazz;
        };
        entity.getClassesByMainType = function (componentType) {
            componentType = parseClassType(componentType);
            var result = [];
            var obj = storage[componentType.main];
            if (obj &amp;&amp; obj[IS_CONTAINER]) {
                zrUtil.each(obj, function (o, type) {
                    type !== IS_CONTAINER &amp;&amp; result.push(o);
                });
            } else {
                result.push(obj);
            }
            return result;
        };
        entity.hasClass = function (componentType) {
            // Just consider componentType.main.
            componentType = parseClassType(componentType);
            return !!storage[componentType.main];
        };
        /**
         * @return {Array.<string>} Like [&apos;aa&apos;, &apos;bb&apos;], but can not be [&apos;aa.xx&apos;]
         */
        entity.getAllClassMainTypes = function () {
            var types = [];
            zrUtil.each(storage, function (obj, type) {
                types.push(type);
            });
            return types;
        };
        /**
         * If a main type is container and has sub types
         * @param  {string}  mainType
         * @return {boolean}
         */
        entity.hasSubTypes = function (componentType) {
            componentType = parseClassType(componentType);
            var obj = storage[componentType.main];
            return obj &amp;&amp; obj[IS_CONTAINER];
        };
        entity.parseClassType = parseClassType;
        function makeContainer(componentType) {
            var container = storage[componentType.main];
            if (!container || !container[IS_CONTAINER]) {
                container = storage[componentType.main] = {};
                container[IS_CONTAINER] = true;
            }
            return container;
        }
        if (options.registerWhenExtend) {
            var originalExtend = entity.extend;
            if (originalExtend) {
                entity.extend = function (proto) {
                    var ExtendedClass = originalExtend.call(this, proto);
                    return entity.registerClass(ExtendedClass, proto.type);
                };
            }
        }
        return entity;
    };
    /**
     * @param {string|Array.<string>} properties
     */
    clazz.setReadOnly = function (obj, properties) {
    };
    return clazz;
});
define(&apos;echarts/model/mixin/areaStyle&apos;, [&apos;require&apos;, &apos;./makeStyleMapper&apos;], function (require) {
    return {
        getAreaStyle: require(&apos;./makeStyleMapper&apos;)([
            [
                &apos;fill&apos;,
                &apos;color&apos;
            ],
            [&apos;shadowBlur&apos;],
            [&apos;shadowOffsetX&apos;],
            [&apos;shadowOffsetY&apos;],
            [&apos;opacity&apos;],
            [&apos;shadowColor&apos;]
        ])
    };
});
define(&apos;echarts/model/mixin/makeStyleMapper&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    return function (properties) {
        // Normalize
        for (var i = 0; i &lt; properties.length; i++) {
            if (!properties[i][1]) {
                properties[i][1] = properties[i][0];
            }
        }
        return function (excludes) {
            var style = {};
            for (var i = 0; i &lt; properties.length; i++) {
                var propName = properties[i][1];
                if (excludes &amp;&amp; zrUtil.indexOf(excludes, propName) &gt;= 0) {
                    continue;
                }
                var val = this.getShallow(propName);
                if (val != null) {
                    style[properties[i][0]] = val;
                }
            }
            return style;
        };
    };
});
define(&apos;zrender/contain/text&apos;, [&apos;require&apos;, &apos;../core/util&apos;, &apos;../core/BoundingRect&apos;], function (require) {
    var textWidthCache = {};
    var textWidthCacheCounter = 0;
    var TEXT_CACHE_MAX = 5000;
    var util = require(&apos;../core/util&apos;);
    var BoundingRect = require(&apos;../core/BoundingRect&apos;);
    var retrieve = util.retrieve;
    function getTextWidth(text, textFont) {
        var key = text + &apos;:&apos; + textFont;
        if (textWidthCache[key]) {
            return textWidthCache[key];
        }
        var textLines = (text + &apos;&apos;).split(&apos;\n&apos;);
        var width = 0;
        for (var i = 0, l = textLines.length; i &lt; l; i++) {
            // measureText &#x53EF;&#x4EE5;&#x88AB;&#x8986;&#x76D6;&#x4EE5;&#x517C;&#x5BB9;&#x4E0D;&#x652F;&#x6301; Canvas &#x7684;&#x73AF;&#x5883;
            width = Math.max(textContain.measureText(textLines[i], textFont).width, width);
        }
        if (textWidthCacheCounter &gt; TEXT_CACHE_MAX) {
            textWidthCacheCounter = 0;
            textWidthCache = {};
        }
        textWidthCacheCounter++;
        textWidthCache[key] = width;
        return width;
    }
    function getTextRect(text, textFont, textAlign, textBaseline) {
        var textLineLen = ((text || &apos;&apos;) + &apos;&apos;).split(&apos;\n&apos;).length;
        var width = getTextWidth(text, textFont);
        // FIXME &#x9AD8;&#x5EA6;&#x8BA1;&#x7B97;&#x6BD4;&#x8F83;&#x7C97;&#x66B4;
        var lineHeight = getTextWidth(&apos;&#x56FD;&apos;, textFont);
        var height = textLineLen * lineHeight;
        var rect = new BoundingRect(0, 0, width, height);
        // Text has a special line height property
        rect.lineHeight = lineHeight;
        switch (textBaseline) {
        case &apos;bottom&apos;:
        case &apos;alphabetic&apos;:
            rect.y -= lineHeight;
            break;
        case &apos;middle&apos;:
            rect.y -= lineHeight / 2;
            break;    // case &apos;hanging&apos;:
                      // case &apos;top&apos;:
        }
        // FIXME Right to left language
        switch (textAlign) {
        case &apos;end&apos;:
        case &apos;right&apos;:
            rect.x -= rect.width;
            break;
        case &apos;center&apos;:
            rect.x -= rect.width / 2;
            break;    // case &apos;start&apos;:
                      // case &apos;left&apos;:
        }
        return rect;
    }
    function adjustTextPositionOnRect(textPosition, rect, textRect, distance) {
        var x = rect.x;
        var y = rect.y;
        var height = rect.height;
        var width = rect.width;
        var textHeight = textRect.height;
        var halfHeight = height / 2 - textHeight / 2;
        var textAlign = &apos;left&apos;;
        switch (textPosition) {
        case &apos;left&apos;:
            x -= distance;
            y += halfHeight;
            textAlign = &apos;right&apos;;
            break;
        case &apos;right&apos;:
            x += distance + width;
            y += halfHeight;
            textAlign = &apos;left&apos;;
            break;
        case &apos;top&apos;:
            x += width / 2;
            y -= distance + textHeight;
            textAlign = &apos;center&apos;;
            break;
        case &apos;bottom&apos;:
            x += width / 2;
            y += height + distance;
            textAlign = &apos;center&apos;;
            break;
        case &apos;inside&apos;:
            x += width / 2;
            y += halfHeight;
            textAlign = &apos;center&apos;;
            break;
        case &apos;insideLeft&apos;:
            x += distance;
            y += halfHeight;
            textAlign = &apos;left&apos;;
            break;
        case &apos;insideRight&apos;:
            x += width - distance;
            y += halfHeight;
            textAlign = &apos;right&apos;;
            break;
        case &apos;insideTop&apos;:
            x += width / 2;
            y += distance;
            textAlign = &apos;center&apos;;
            break;
        case &apos;insideBottom&apos;:
            x += width / 2;
            y += height - textHeight - distance;
            textAlign = &apos;center&apos;;
            break;
        case &apos;insideTopLeft&apos;:
            x += distance;
            y += distance;
            textAlign = &apos;left&apos;;
            break;
        case &apos;insideTopRight&apos;:
            x += width - distance;
            y += distance;
            textAlign = &apos;right&apos;;
            break;
        case &apos;insideBottomLeft&apos;:
            x += distance;
            y += height - textHeight - distance;
            break;
        case &apos;insideBottomRight&apos;:
            x += width - distance;
            y += height - textHeight - distance;
            textAlign = &apos;right&apos;;
            break;
        }
        return {
            x: x,
            y: y,
            textAlign: textAlign,
            textBaseline: &apos;top&apos;
        };
    }
    /**
     * Show ellipsis if overflow.
     *
     * @param  {string} text
     * @param  {string} containerWidth
     * @param  {string} textFont
     * @param  {number} [ellipsis=&apos;...&apos;]
     * @param  {Object} [options]
     * @param  {number} [options.maxIterations=3]
     * @param  {number} [options.minChar=0] If truncate result are less
     *                  then minChar, ellipsis will not show, which is
     *                  better for user hint in some cases.
     * @param  {number} [options.placeholder=&apos;&apos;] When all truncated, use the placeholder.
     * @return {string}
     */
    function truncateText(text, containerWidth, textFont, ellipsis, options) {
        if (!containerWidth) {
            return &apos;&apos;;
        }
        options = options || {};
        ellipsis = retrieve(ellipsis, &apos;...&apos;);
        var maxIterations = retrieve(options.maxIterations, 2);
        var minChar = retrieve(options.minChar, 0);
        // FIXME
        // Other languages?
        var cnCharWidth = getTextWidth(&apos;&#x56FD;&apos;, textFont);
        // FIXME
        // Consider proportional font?
        var ascCharWidth = getTextWidth(&apos;a&apos;, textFont);
        var placeholder = retrieve(options.placeholder, &apos;&apos;);
        // Example 1: minChar: 3, text: &apos;asdfzxcv&apos;, truncate result: &apos;asdf&apos;, but not: &apos;a...&apos;.
        // Example 2: minChar: 3, text: &apos;&#x7EF4;&#x5EA6;&apos;, truncate result: &apos;&#x7EF4;&apos;, but not: &apos;...&apos;.
        var contentWidth = containerWidth = Math.max(0, containerWidth - 1);
        // Reserve some gap.
        for (var i = 0; i &lt; minChar &amp;&amp; contentWidth &gt;= ascCharWidth; i++) {
            contentWidth -= ascCharWidth;
        }
        var ellipsisWidth = getTextWidth(ellipsis);
        if (ellipsisWidth &gt; contentWidth) {
            ellipsis = &apos;&apos;;
            ellipsisWidth = 0;
        }
        contentWidth = containerWidth - ellipsisWidth;
        var textLines = (text + &apos;&apos;).split(&apos;\n&apos;);
        for (var i = 0, len = textLines.length; i &lt; len; i++) {
            var textLine = textLines[i];
            var lineWidth = getTextWidth(textLine, textFont);
            if (lineWidth <= containerwidth)="" {="" continue;="" }="" for="" (var="" j="0;;" j++)="" if="" (linewidth="" <="contentWidth" ||="">= maxIterations) {
                    textLine += ellipsis;
                    break;
                }
                var subLength = j === 0 ? estimateLength(textLine, contentWidth, ascCharWidth, cnCharWidth) : lineWidth &gt; 0 ? Math.floor(textLine.length * contentWidth / lineWidth) : 0;
                textLine = textLine.substr(0, subLength);
                lineWidth = getTextWidth(textLine, textFont);
            }
            if (textLine === &apos;&apos;) {
                textLine = placeholder;
            }
            textLines[i] = textLine;
        }
        return textLines.join(&apos;\n&apos;);
    }
    function estimateLength(text, contentWidth, ascCharWidth, cnCharWidth) {
        var width = 0;
        var i = 0;
        for (var len = text.length; i &lt; len &amp;&amp; width &lt; contentWidth; i++) {
            var charCode = text.charCodeAt(i);
            width += 0 <= 1="" 5="" 360="" charcode="" &&="" <="127" ?="" asccharwidth="" :="" cncharwidth;="" }="" return="" i;="" var="" textcontain="{" getwidth:="" gettextwidth,="" getboundingrect:="" gettextrect,="" adjusttextpositiononrect:="" adjusttextpositiononrect,="" truncatetext:="" truncatetext,="" measuretext:="" function="" (text,="" textfont)="" {="" ctx="util.getContext();" ctx.font="textFont" ||="" '12px="" sans-serif';="" ctx.measuretext(text);="" };="" textcontain;="" });="" define('echarts="" model="" mixin="" itemstyle',="" ['require',="" '.="" makestylemapper'],="" (require)="" getitemstyle="require(&apos;./makeStyleMapper&apos;)([" [="" 'fill',="" 'color'="" ],="" 'stroke',="" 'bordercolor'="" 'linewidth',="" 'borderwidth'="" ['opacity'],="" ['shadowblur'],="" ['shadowoffsetx'],="" ['shadowoffsety'],="" ['shadowcolor']="" ]);="" getitemstyle:="" (excludes)="" style="getItemStyle.call(this," excludes);="" linedash="this.getBorderLineDash();" (style.linedash="lineDash);" style;="" },="" getborderlinedash:="" ()="" linetype="this.get(&apos;borderType&apos;);" 'solid'="" null="" 'dashed'="" 5,="" ]="" 1,="" ];="" coord="" polar="" radiusaxis',="" 'zrender="" core="" util',="" '..="" axis'],="" 'use="" strict';="" zrutil="require(&apos;zrender/core/util&apos;);" axis="require(&apos;../Axis&apos;);" radiusaxis(scale,="" radiusextent)="" axis.call(this,="" 'radius',="" scale,="" radiusextent);="" **="" *="" type="" -="" 'category'="" 'value'="" 'time'="" 'log'="" @type="" {string}="" this.type="category" ;="" radiusaxis.prototype="{" constructor:="" radiusaxis,="" datatoradius:="" axis.prototype.datatocoord,="" radiustodata:="" axis.prototype.coordtodata="" zrutil.inherits(radiusaxis,="" axis);="" radiusaxis;="" angleaxis',="" angleaxis(scale,="" angleextent)="" angleextent="angleExtent" 0,="" 'angle',="" angleextent);="" angleaxis.prototype="{" angleaxis,="" datatoangle:="" angletodata:="" zrutil.inherits(angleaxis,="" angleaxis;="" define('zrender="" boundingrect',="" vector',="" matrix'],="" vec2="require(&apos;./vector&apos;);" matrix="require(&apos;./matrix&apos;);" v2applytransform="vec2.applyTransform;" mathmin="Math.min;" mathabs="Math.abs;" mathmax="Math.max;" @alias="" module:echarts="" boundingrect="" boundingrect(x,="" y,="" width,="" height)="" {number}="" this.x="x;" this.y="y;" this.width="width;" this.height="height;" boundingrect.prototype="{" boundingrect,="" union:="" (other)="" x="mathMin(other.x," this.x);="" y="mathMin(other.y," this.y);="" +="" other.width,="" this.width)="" x;="" other.height,="" this.height)="" y;="" applytransform:="" min="[];" max="[];" (m)="" in="" case="" usage="" like="" this="" el.getboundingrect().applytransform(el.transform)="" and="" element="" has="" no="" transform="" if="" (!m)="" return;="" min[0]="this.x;" min[1]="this.y;" max[0]="this.x" this.width;="" max[1]="this.y" this.height;="" v2applytransform(min,="" min,="" m);="" v2applytransform(max,="" max,="" max[0]);="" max[1]);="" min[0]);="" min[1]);="" }(),="" calculatetransform:="" (b)="" a="this;" sx="b.width" a.width;="" sy="b.height" a.height;="" m="matrix.create();" 矩阵右乘="" matrix.translate(m,="" m,="" -a.x,="" -a.y="" matrix.scale(m,="" sx,="" b.x,="" b.y="" m;="" intersect:="" ax0="a.x;" ax1="a.x" ay0="a.y;" ay1="a.y" bx0="b.x;" bx1="b.x" b.width;="" by0="b.y;" by1="b.y" b.height;="" !(ax1="" ay0);="" contain:="" (x,="" y)="" rect="this;">= rect.x &amp;&amp; x <= rect.x="" +="" rect.width="" &&="" y="">= rect.y &amp;&amp; y <= 1="" rect.y="" +="" rect.height;="" },="" clone:="" function="" ()="" {="" return="" new="" boundingrect(this.x,="" this.y,="" this.width,="" this.height);="" copy:="" (other)="" this.x="other.x;" this.y="other.y;" this.width="other.width;" this.height="other.height;" }="" };="" boundingrect;="" });="" define('echarts="" coord="" axis',="" ['require',="" '..="" util="" number',="" 'zrender="" core="" util'],="" (require)="" var="" numberutil="require(&apos;../util/number&apos;);" linearmap="numberUtil.linearMap;" zrutil="require(&apos;zrender/core/util&apos;);" fixextentwithbands(extent,="" ntick)="" size="extent[1]" -="" extent[0];="" len="nTick;" margin="size" 2;="" extent[0]="" extent[1]="" normalizedextent="[" 0,="" ];="" **="" *="" @name="" module:echarts="" cartesianaxis="" @constructor="" axis="function" (dim,="" scale,="" extent)="" dimension.="" such="" as="" 'x',="" 'y',="" 'z',="" 'angle',="" 'radius'="" @type="" {string}="" this.dim="dim;" scale="" {module:echarts="" *}="" this.scale="scale;" {array.<number="">}
         * @private
         */
        this._extent = extent || [
            0,
            0
        ];
        /**
         * @type {boolean}
         */
        this.inverse = false;
        /**
         * Usually true when axis has a ordinal scale
         * @type {boolean}
         */
        this.onBand = false;
    };
    Axis.prototype = {
        constructor: Axis,
        contain: function (coord) {
            var extent = this._extent;
            var min = Math.min(extent[0], extent[1]);
            var max = Math.max(extent[0], extent[1]);
            return coord &gt;= min &amp;&amp; coord <= 0="" 1="" max;="" },="" containdata:="" function="" (data)="" {="" return="" this.contain(this.datatocoord(data));="" getextent:="" ()="" var="" ret="this._extent.slice();" ret;="" getpixelprecision:="" (dataextent)="" numberutil.getpixelprecision(dataextent="" ||="" this.scale.getextent(),="" this._extent);="" setextent:="" (start,="" end)="" extent="this._extent;" extent[0]="start;" extent[1]="end;" datatocoord:="" (data,="" clamp)="" scale="this.scale;" data="scale.normalize(data);" if="" (this.onband="" &&="" scale.type="==" 'ordinal')="" fixextentwithbands(extent,="" scale.count());="" }="" linearmap(data,="" normalizedextent,="" extent,="" clamp);="" coordtodata:="" (coord,="" t="linearMap(coord," this.scale.scale(t);="" gettickscoords:="" (alignwithlabel)="" !alignwithlabel)="" bands="this.getBands();" coords="[];" for="" (var="" i="0;" <="" bands.length;="" i++)="" coords.push(bands[i][0]);="" (bands[i="" -="" 1])="" coords.push(bands[i="" 1][1]);="" coords;="" else="" zrutil.map(this.scale.getticks(),="" this.datatocoord,="" this);="" getlabelscoords:="" getbands:="" len="this.scale.count();" start="extent[0];" end="extent[1];" span="end" start;="" len;="" bands.push([="" *="" +="" start,="" (i="" 1)="" ]);="" bands;="" getbandwidth:="" axisextent="this._extent;" dataextent="this.scale.getExtent();" dataextent[0]="" ?="" :="" 0);="" fix="" #2728,="" avoid="" nan="" when="" only="" one="" data.="" (len="1);" size="Math.abs(axisExtent[1]" axisextent[0]);="" math.abs(size)="" };="" axis;="" });="" define('echarts="" util="" component',="" ['require',="" 'zrender="" core="" util',="" '.="" clazz'],="" (require)="" zrutil="require(&apos;zrender/core/util&apos;);" clazz="require(&apos;./clazz&apos;);" parseclasstype="clazz.parseClassType;" base="0;" componentutil="{};" delimiter="_" ;="" **="" @public="" @param="" {string}="" type="" @return="" componentutil.getuid="function" (type)="" considering="" the="" case="" of="" crossing="" js="" context,="" use="" math.random="" to="" make="" id="" as="" unique="" possible.="" [="" '',="" base++,="" math.random()="" ].join(delimiter);="" @inner="" componentutil.enablesubtypedefaulter="function" (entity)="" subtypedefaulters="{};" entity.registersubtypedefaulter="function" (componenttype,="" defaulter)="" componenttype="parseClassType(componentType);" subtypedefaulters[componenttype.main]="defaulter;" entity.determinesubtype="function" option)="" (!type)="" componenttypemain="parseClassType(componentType).main;" (entity.hassubtypes(componenttype)="" subtypedefaulters[componenttypemain])="" type;="" entity;="" topological="" travel="" on="" activity="" network="" (activity="" vertices).="" dependencies="" is="" defined="" in="" model.prototype.dependencies,="" like="" ['xaxis',="" 'yaxis'].="" 'xaxis'="" or="" 'yaxis'="" absent="" componenttypelist,="" just="" ignore="" it="" topology.="" there="" circle="" dependencey,="" error="" will="" be="" thrown.="" componentutil.enabletopologicaltravel="function" (entity,="" dependencygetter)="" {array.<string="">} targetNameList Target Component type list.
         *                                           Can be [&apos;aa&apos;, &apos;bb&apos;, &apos;aa.xx&apos;]
         * @param {Array.<string>} fullNameList By which we can build dependency graph.
         * @param {Function} callback Params: componentType, dependencies.
         * @param {Object} context Scope of callback.
         */
        entity.topologicalTravel = function (targetNameList, fullNameList, callback, context) {
            if (!targetNameList.length) {
                return;
            }
            var result = makeDepndencyGraph(fullNameList);
            var graph = result.graph;
            var stack = result.noEntryList;
            var targetNameSet = {};
            zrUtil.each(targetNameList, function (name) {
                targetNameSet[name] = true;
            });
            while (stack.length) {
                var currComponentType = stack.pop();
                var currVertex = graph[currComponentType];
                var isInTargetNameSet = !!targetNameSet[currComponentType];
                if (isInTargetNameSet) {
                    callback.call(context, currComponentType, currVertex.originalDeps.slice());
                    delete targetNameSet[currComponentType];
                }
                zrUtil.each(currVertex.successor, isInTargetNameSet ? removeEdgeAndAdd : removeEdge);
            }
            zrUtil.each(targetNameSet, function () {
                throw new Error(&apos;Circle dependency may exists&apos;);
            });
            function removeEdge(succComponentType) {
                graph[succComponentType].entryCount--;
                if (graph[succComponentType].entryCount === 0) {
                    stack.push(succComponentType);
                }
            }
            // Consider this case: legend depends on series, and we call
            // chart.setOption({series: [...]}), where only series is in option.
            // If we do not have &apos;removeEdgeAndAdd&apos;, legendModel.mergeOption will
            // not be called, but only sereis.mergeOption is called. Thus legend
            // have no chance to update its local record about series (like which
            // name of series is available in legend).
            function removeEdgeAndAdd(succComponentType) {
                targetNameSet[succComponentType] = true;
                removeEdge(succComponentType);
            }
        };
        /**
         * DepndencyGraph: {Object}
         * key: conponentType,
         * value: {
         *     successor: [conponentTypes...],
         *     originalDeps: [conponentTypes...],
         *     entryCount: {number}
         * }
         */
        function makeDepndencyGraph(fullNameList) {
            var graph = {};
            var noEntryList = [];
            zrUtil.each(fullNameList, function (name) {
                var thisItem = createDependencyGraphItem(graph, name);
                var originalDeps = thisItem.originalDeps = dependencyGetter(name);
                var availableDeps = getAvailableDependencies(originalDeps, fullNameList);
                thisItem.entryCount = availableDeps.length;
                if (thisItem.entryCount === 0) {
                    noEntryList.push(name);
                }
                zrUtil.each(availableDeps, function (dependentName) {
                    if (zrUtil.indexOf(thisItem.predecessor, dependentName) &lt; 0) {
                        thisItem.predecessor.push(dependentName);
                    }
                    var thatItem = createDependencyGraphItem(graph, dependentName);
                    if (zrUtil.indexOf(thatItem.successor, dependentName) &lt; 0) {
                        thatItem.successor.push(name);
                    }
                });
            });
            return {
                graph: graph,
                noEntryList: noEntryList
            };
        }
        function createDependencyGraphItem(graph, name) {
            if (!graph[name]) {
                graph[name] = {
                    predecessor: [],
                    successor: []
                };
            }
            return graph[name];
        }
        function getAvailableDependencies(originalDeps, fullNameList) {
            var availableDeps = [];
            zrUtil.each(originalDeps, function (dep) {
                zrUtil.indexOf(fullNameList, dep) &gt;= 0 &amp;&amp; availableDeps.push(dep);
            });
            return availableDeps;
        }
    };
    return componentUtil;
});
define(&apos;echarts/model/mixin/boxLayout&apos;, [&apos;require&apos;], function (require) {
    return {
        getBoxLayoutParams: function () {
            return {
                left: this.get(&apos;left&apos;),
                top: this.get(&apos;top&apos;),
                right: this.get(&apos;right&apos;),
                bottom: this.get(&apos;bottom&apos;),
                width: this.get(&apos;width&apos;),
                height: this.get(&apos;height&apos;)
            };
        }
    };
});
define(&apos;echarts/scale/Ordinal&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;./Scale&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var Scale = require(&apos;./Scale&apos;);
    var scaleProto = Scale.prototype;
    var OrdinalScale = Scale.extend({
            type: &apos;ordinal&apos;,
            init: function (data, extent) {
                this._data = data;
                this._extent = extent || [
                    0,
                    data.length - 1
                ];
            },
            parse: function (val) {
                return typeof val === &apos;string&apos; ? zrUtil.indexOf(this._data, val) : Math.round(val);
            },
            contain: function (rank) {
                rank = this.parse(rank);
                return scaleProto.contain.call(this, rank) &amp;&amp; this._data[rank] != null;
            },
            normalize: function (val) {
                return scaleProto.normalize.call(this, this.parse(val));
            },
            scale: function (val) {
                return Math.round(scaleProto.scale.call(this, val));
            },
            getTicks: function () {
                var ticks = [];
                var extent = this._extent;
                var rank = extent[0];
                while (rank <= extent[1])="" {="" ticks.push(rank);="" rank++;="" }="" return="" ticks;="" },="" getlabel:="" function="" (n)="" this._data[n];="" count:="" ()="" this._extent[1]="" -="" this._extent[0]="" +="" 1;="" niceticks:="" zrutil.noop,="" niceextent:="" zrutil.noop="" });="" **="" *="" @return="" {module:echarts="" scale="" time}="" ordinalscale.create="function" new="" ordinalscale();="" };="" ordinalscale;="" define('zrender="" container="" group',="" ['require',="" '..="" core="" util',="" element',="" boundingrect'],="" (require)="" var="" zrutil="require(&apos;../core/util&apos;);" element="require(&apos;../Element&apos;);" boundingrect="require(&apos;../core/BoundingRect&apos;);" @alias="" module:zrender="" graphic="" group="" @constructor="" @extends="" mixin="" transformable="" eventful="" (opts)="" opts="opts" ||="" {};="" element.call(this,="" opts);="" for="" (var="" key="" in="" opts)="" this[key]="opts[key];" this._children="[];" this.__storage="null;" this.__dirty="true;" group.prototype="{" constructor:="" group,="" isgroup:="" true,="" type:="" 'group',="" silent:="" false,="" children:="" this._children.slice();="" childat:="" (idx)="" this._children[idx];="" childofname:="" (name)="" children="this._children;" i="0;" <="" children.length;="" i++)="" if="" (children[i].name="==" name)="" children[i];="" childcount:="" this._children.length;="" add:="" (child)="" (child="" &&="" child="" !="=" this="" child.parent="" this)="" this._children.push(child);="" this._doadd(child);="" this;="" addbefore:="" (child,="" nextsibling)="" nextsibling="" nextsibling.parent="==" idx="children.indexOf(nextSibling);" (idx="">= 0) {
                    children.splice(idx, 0, child);
                    this._doAdd(child);
                }
            }
            return this;
        },
        _doAdd: function (child) {
            if (child.parent) {
                child.parent.remove(child);
            }
            child.parent = this;
            var storage = this.__storage;
            var zr = this.__zr;
            if (storage &amp;&amp; storage !== child.__storage) {
                storage.addToMap(child);
                if (child instanceof Group) {
                    child.addChildrenToStorage(storage);
                }
            }
            zr &amp;&amp; zr.refresh();
        },
        remove: function (child) {
            var zr = this.__zr;
            var storage = this.__storage;
            var children = this._children;
            var idx = zrUtil.indexOf(children, child);
            if (idx &lt; 0) {
                return this;
            }
            children.splice(idx, 1);
            child.parent = null;
            if (storage) {
                storage.delFromMap(child.id);
                if (child instanceof Group) {
                    child.delChildrenFromStorage(storage);
                }
            }
            zr &amp;&amp; zr.refresh();
            return this;
        },
        removeAll: function () {
            var children = this._children;
            var storage = this.__storage;
            var child;
            var i;
            for (i = 0; i &lt; children.length; i++) {
                child = children[i];
                if (storage) {
                    storage.delFromMap(child.id);
                    if (child instanceof Group) {
                        child.delChildrenFromStorage(storage);
                    }
                }
                child.parent = null;
            }
            children.length = 0;
            return this;
        },
        eachChild: function (cb, context) {
            var children = this._children;
            for (var i = 0; i &lt; children.length; i++) {
                var child = children[i];
                cb.call(context, child, i);
            }
            return this;
        },
        traverse: function (cb, context) {
            for (var i = 0; i &lt; this._children.length; i++) {
                var child = this._children[i];
                cb.call(context, child);
                if (child.type === &apos;group&apos;) {
                    child.traverse(cb, context);
                }
            }
            return this;
        },
        addChildrenToStorage: function (storage) {
            for (var i = 0; i &lt; this._children.length; i++) {
                var child = this._children[i];
                storage.addToMap(child);
                if (child instanceof Group) {
                    child.addChildrenToStorage(storage);
                }
            }
        },
        delChildrenFromStorage: function (storage) {
            for (var i = 0; i &lt; this._children.length; i++) {
                var child = this._children[i];
                storage.delFromMap(child.id);
                if (child instanceof Group) {
                    child.delChildrenFromStorage(storage);
                }
            }
        },
        dirty: function () {
            this.__dirty = true;
            this.__zr &amp;&amp; this.__zr.refresh();
            return this;
        },
        getBoundingRect: function (includeChildren) {
            // TODO Caching
            // TODO Transform
            var rect = null;
            var tmpRect = new BoundingRect(0, 0, 0, 0);
            var children = includeChildren || this._children;
            var tmpMat = [];
            for (var i = 0; i &lt; children.length; i++) {
                var child = children[i];
                if (child.ignore || child.invisible) {
                    continue;
                }
                var childRect = child.getBoundingRect();
                var transform = child.getLocalTransform(tmpMat);
                if (transform) {
                    tmpRect.copy(childRect);
                    tmpRect.applyTransform(transform);
                    rect = rect || tmpRect.clone();
                    rect.union(tmpRect);
                } else {
                    rect = rect || childRect.clone();
                    rect.union(childRect);
                }
            }
            return rect || tmpRect;
        }
    };
    zrUtil.inherits(Group, Element);
    return Group;
});
define(&apos;echarts/coord/polar/AxisModel&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../../model/Component&apos;, &apos;../axisModelCreator&apos;, &apos;../axisModelCommonMixin&apos;], function (require) {
    &apos;use strict&apos;;
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var ComponentModel = require(&apos;../../model/Component&apos;);
    var axisModelCreator = require(&apos;../axisModelCreator&apos;);
    var PolarAxisModel = ComponentModel.extend({
            type: &apos;polarAxis&apos;,
            axis: null
        });
    zrUtil.merge(PolarAxisModel.prototype, require(&apos;../axisModelCommonMixin&apos;));
    var polarAxisDefaultExtendedOption = {
            angle: {
                polarIndex: 0,
                startAngle: 90,
                clockwise: true,
                splitNumber: 12,
                axisLabel: { rotate: false }
            },
            radius: {
                polarIndex: 0,
                splitNumber: 5
            }
        };
    function getAxisType(axisDim, option) {
        // Default axis with data is category axis
        return option.type || (option.data ? &apos;category&apos; : &apos;value&apos;);
    }
    axisModelCreator(&apos;angle&apos;, PolarAxisModel, getAxisType, polarAxisDefaultExtendedOption.angle);
    axisModelCreator(&apos;radius&apos;, PolarAxisModel, getAxisType, polarAxisDefaultExtendedOption.radius);
});
define(&apos;zrender/Element&apos;, [&apos;require&apos;, &apos;./core/guid&apos;, &apos;./mixin/Eventful&apos;, &apos;./mixin/Transformable&apos;, &apos;./mixin/Animatable&apos;, &apos;./core/util&apos;], function (require) {
    &apos;use strict&apos;;
    var guid = require(&apos;./core/guid&apos;);
    var Eventful = require(&apos;./mixin/Eventful&apos;);
    var Transformable = require(&apos;./mixin/Transformable&apos;);
    var Animatable = require(&apos;./mixin/Animatable&apos;);
    var zrUtil = require(&apos;./core/util&apos;);
    /**
     * @alias module:zrender/Element
     * @constructor
     * @extends {module:zrender/mixin/Animatable}
     * @extends {module:zrender/mixin/Transformable}
     * @extends {module:zrender/mixin/Eventful}
     */
    var Element = function (opts) {
        Transformable.call(this, opts);
        Eventful.call(this, opts);
        Animatable.call(this, opts);
        /**
         * &#x753B;&#x5E03;&#x5143;&#x7D20;ID
         * @type {string}
         */
        this.id = opts.id || guid();
    };
    Element.prototype = {
        type: &apos;element&apos;,
        name: &apos;&apos;,
        __zr: null,
        ignore: false,
        clipPath: null,
        drift: function (dx, dy) {
            switch (this.draggable) {
            case &apos;horizontal&apos;:
                dy = 0;
                break;
            case &apos;vertical&apos;:
                dx = 0;
                break;
            }
            var m = this.transform;
            if (!m) {
                m = this.transform = [
                    1,
                    0,
                    0,
                    1,
                    0,
                    0
                ];
            }
            m[4] += dx;
            m[5] += dy;
            this.decomposeTransform();
            this.dirty(false);
        },
        beforeUpdate: function () {
        },
        afterUpdate: function () {
        },
        update: function () {
            this.updateTransform();
        },
        traverse: function (cb, context) {
        },
        attrKV: function (key, value) {
            if (key === &apos;position&apos; || key === &apos;scale&apos; || key === &apos;origin&apos;) {
                // Copy the array
                if (value) {
                    var target = this[key];
                    if (!target) {
                        target = this[key] = [];
                    }
                    target[0] = value[0];
                    target[1] = value[1];
                }
            } else {
                this[key] = value;
            }
        },
        hide: function () {
            this.ignore = true;
            this.__zr &amp;&amp; this.__zr.refresh();
        },
        show: function () {
            this.ignore = false;
            this.__zr &amp;&amp; this.__zr.refresh();
        },
        attr: function (key, value) {
            if (typeof key === &apos;string&apos;) {
                this.attrKV(key, value);
            } else if (zrUtil.isObject(key)) {
                for (var name in key) {
                    if (key.hasOwnProperty(name)) {
                        this.attrKV(name, key[name]);
                    }
                }
            }
            this.dirty(false);
            return this;
        },
        setClipPath: function (clipPath) {
            var zr = this.__zr;
            if (zr) {
                clipPath.addSelfToZr(zr);
            }
            // Remove previous clip path
            if (this.clipPath &amp;&amp; this.clipPath !== clipPath) {
                this.removeClipPath();
            }
            this.clipPath = clipPath;
            clipPath.__zr = zr;
            clipPath.__clipTarget = this;
            this.dirty(false);
        },
        removeClipPath: function () {
            var clipPath = this.clipPath;
            if (clipPath) {
                if (clipPath.__zr) {
                    clipPath.removeSelfFromZr(clipPath.__zr);
                }
                clipPath.__zr = null;
                clipPath.__clipTarget = null;
                this.clipPath = null;
                this.dirty(false);
            }
        },
        addSelfToZr: function (zr) {
            this.__zr = zr;
            // &#x6DFB;&#x52A0;&#x52A8;&#x753B;
            var animators = this.animators;
            if (animators) {
                for (var i = 0; i &lt; animators.length; i++) {
                    zr.animation.addAnimator(animators[i]);
                }
            }
            if (this.clipPath) {
                this.clipPath.addSelfToZr(zr);
            }
        },
        removeSelfFromZr: function (zr) {
            this.__zr = null;
            // &#x79FB;&#x9664;&#x52A8;&#x753B;
            var animators = this.animators;
            if (animators) {
                for (var i = 0; i &lt; animators.length; i++) {
                    zr.animation.removeAnimator(animators[i]);
                }
            }
            if (this.clipPath) {
                this.clipPath.removeSelfFromZr(zr);
            }
        }
    };
    zrUtil.mixin(Element, Animatable);
    zrUtil.mixin(Element, Transformable);
    zrUtil.mixin(Element, Eventful);
    return Element;
});
define(&apos;echarts/coord/axisModelCreator&apos;, [&apos;require&apos;, &apos;./axisDefault&apos;, &apos;zrender/core/util&apos;, &apos;../model/Component&apos;, &apos;../util/layout&apos;], function (require) {
    var axisDefault = require(&apos;./axisDefault&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var ComponentModel = require(&apos;../model/Component&apos;);
    var layout = require(&apos;../util/layout&apos;);
    // FIXME axisType is fixed ?
    var AXIS_TYPES = [
            &apos;value&apos;,
            &apos;category&apos;,
            &apos;time&apos;,
            &apos;log&apos;
        ];
    /**
     * Generate sub axis model class
     * @param {string} axisName &apos;x&apos; &apos;y&apos; &apos;radius&apos; &apos;angle&apos; &apos;parallel&apos;
     * @param {module:echarts/model/Component} BaseAxisModelClass
     * @param {Function} axisTypeDefaulter
     * @param {Object} [extraDefaultOption]
     */
    return function (axisName, BaseAxisModelClass, axisTypeDefaulter, extraDefaultOption) {
        zrUtil.each(AXIS_TYPES, function (axisType) {
            BaseAxisModelClass.extend({
                type: axisName + &apos;Axis.&apos; + axisType,
                mergeDefaultAndTheme: function (option, ecModel) {
                    var layoutMode = this.layoutMode;
                    var inputPositionParams = layoutMode ? layout.getLayoutParams(option) : {};
                    var themeModel = ecModel.getTheme();
                    zrUtil.merge(option, themeModel.get(axisType + &apos;Axis&apos;));
                    zrUtil.merge(option, this.getDefaultOption());
                    option.type = axisTypeDefaulter(axisName, option);
                    if (layoutMode) {
                        layout.mergeLayoutParam(option, inputPositionParams, layoutMode);
                    }
                },
                defaultOption: zrUtil.mergeAll([
                    {},
                    axisDefault[axisType + &apos;Axis&apos;],
                    extraDefaultOption
                ], true)
            });
        });
        ComponentModel.registerSubTypeDefaulter(axisName + &apos;Axis&apos;, zrUtil.curry(axisTypeDefaulter, axisName));
    };
});
define(&apos;echarts/coord/axisModelCommonMixin&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;./axisHelper&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var axisHelper = require(&apos;./axisHelper&apos;);
    function getName(obj) {
        if (zrUtil.isObject(obj) &amp;&amp; obj.value != null) {
            return obj.value;
        } else {
            return obj;
        }
    }
    /**
     * Get categories
     */
    function getCategories() {
        return this.get(&apos;type&apos;) === &apos;category&apos; &amp;&amp; zrUtil.map(this.get(&apos;data&apos;), getName);
    }
    /**
     * Format labels
     * @return {Array.<string>}
     */
    function getFormattedLabels() {
        return axisHelper.getFormattedLabels(this.axis, this.get(&apos;axisLabel.formatter&apos;));
    }
    return {
        getFormattedLabels: getFormattedLabels,
        getCategories: getCategories
    };
});
define(&apos;zrender/core/guid&apos;, [], function () {
    var idStart = 2311;
    return function () {
        return idStart++;
    };
});
define(&apos;zrender/mixin/Transformable&apos;, [&apos;require&apos;, &apos;../core/matrix&apos;, &apos;../core/vector&apos;], function (require) {
    &apos;use strict&apos;;
    var matrix = require(&apos;../core/matrix&apos;);
    var vector = require(&apos;../core/vector&apos;);
    var mIdentity = matrix.identity;
    var EPSILON = 0.00005;
    function isNotAroundZero(val) {
        return val &gt; EPSILON || val &lt; -EPSILON;
    }
    /**
     * @alias module:zrender/mixin/Transformable
     * @constructor
     */
    var Transformable = function (opts) {
        opts = opts || {};
        // If there are no given position, rotation, scale
        if (!opts.position) {
            /**
             * &#x5E73;&#x79FB;
             * @type {Array.<number>}
             * @default [0, 0]
             */
            this.position = [
                0,
                0
            ];
        }
        if (opts.rotation == null) {
            /**
             * &#x65CB;&#x8F6C;
             * @type {Array.<number>}
             * @default 0
             */
            this.rotation = 0;
        }
        if (!opts.scale) {
            /**
             * &#x7F29;&#x653E;
             * @type {Array.<number>}
             * @default [1, 1]
             */
            this.scale = [
                1,
                1
            ];
        }
        /**
         * &#x65CB;&#x8F6C;&#x548C;&#x7F29;&#x653E;&#x7684;&#x539F;&#x70B9;
         * @type {Array.<number>}
         * @default null
         */
        this.origin = this.origin || null;
    };
    var transformableProto = Transformable.prototype;
    transformableProto.transform = null;
    /**
     * &#x5224;&#x65AD;&#x662F;&#x5426;&#x9700;&#x8981;&#x6709;&#x5750;&#x6807;&#x53D8;&#x6362;
     * &#x5982;&#x679C;&#x6709;&#x5750;&#x6807;&#x53D8;&#x6362;, &#x5219;&#x4ECE;position, rotation, scale&#x4EE5;&#x53CA;&#x7236;&#x8282;&#x70B9;&#x7684;transform&#x8BA1;&#x7B97;&#x51FA;&#x81EA;&#x8EAB;&#x7684;transform&#x77E9;&#x9635;
     */
    transformableProto.needLocalTransform = function () {
        return isNotAroundZero(this.rotation) || isNotAroundZero(this.position[0]) || isNotAroundZero(this.position[1]) || isNotAroundZero(this.scale[0] - 1) || isNotAroundZero(this.scale[1] - 1);
    };
    transformableProto.updateTransform = function () {
        var parent = this.parent;
        var parentHasTransform = parent &amp;&amp; parent.transform;
        var needLocalTransform = this.needLocalTransform();
        var m = this.transform;
        if (!(needLocalTransform || parentHasTransform)) {
            m &amp;&amp; mIdentity(m);
            return;
        }
        m = m || matrix.create();
        if (needLocalTransform) {
            this.getLocalTransform(m);
        } else {
            mIdentity(m);
        }
        // &#x5E94;&#x7528;&#x7236;&#x8282;&#x70B9;&#x53D8;&#x6362;
        if (parentHasTransform) {
            if (needLocalTransform) {
                matrix.mul(m, parent.transform, m);
            } else {
                matrix.copy(m, parent.transform);
            }
        }
        // &#x4FDD;&#x5B58;&#x8FD9;&#x4E2A;&#x53D8;&#x6362;&#x77E9;&#x9635;
        this.transform = m;
        this.invTransform = this.invTransform || matrix.create();
        matrix.invert(this.invTransform, m);
    };
    transformableProto.getLocalTransform = function (m) {
        m = m || [];
        mIdentity(m);
        var origin = this.origin;
        var scale = this.scale;
        var rotation = this.rotation;
        var position = this.position;
        if (origin) {
            // Translate to origin
            m[4] -= origin[0];
            m[5] -= origin[1];
        }
        matrix.scale(m, m, scale);
        if (rotation) {
            matrix.rotate(m, m, rotation);
        }
        if (origin) {
            // Translate back from origin
            m[4] += origin[0];
            m[5] += origin[1];
        }
        m[4] += position[0];
        m[5] += position[1];
        return m;
    };
    /**
     * &#x5C06;&#x81EA;&#x5DF1;&#x7684;transform&#x5E94;&#x7528;&#x5230;context&#x4E0A;
     * @param {Context2D} ctx
     */
    transformableProto.setTransform = function (ctx) {
        var m = this.transform;
        if (m) {
            ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
        }
    };
    transformableProto.restoreTransform = function (ctx) {
        var m = this.invTransform;
        if (m) {
            ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
        }
    };
    var tmpTransform = [];
    /**
     * &#x5206;&#x89E3;`transform`&#x77E9;&#x9635;&#x5230;`position`, `rotation`, `scale`
     */
    transformableProto.decomposeTransform = function () {
        if (!this.transform) {
            return;
        }
        var parent = this.parent;
        var m = this.transform;
        if (parent &amp;&amp; parent.transform) {
            // Get local transform and decompose them to position, scale, rotation
            matrix.mul(tmpTransform, parent.invTransform, m);
            m = tmpTransform;
        }
        var sx = m[0] * m[0] + m[1] * m[1];
        var sy = m[2] * m[2] + m[3] * m[3];
        var position = this.position;
        var scale = this.scale;
        if (isNotAroundZero(sx - 1)) {
            sx = Math.sqrt(sx);
        }
        if (isNotAroundZero(sy - 1)) {
            sy = Math.sqrt(sy);
        }
        if (m[0] &lt; 0) {
            sx = -sx;
        }
        if (m[3] &lt; 0) {
            sy = -sy;
        }
        position[0] = m[4];
        position[1] = m[5];
        scale[0] = sx;
        scale[1] = sy;
        this.rotation = Math.atan2(-m[1] / sy, m[0] / sx);
    };
    /**
     * Get global scale
     * @return {Array.<number>}
     */
    transformableProto.getGlobalScale = function () {
        var m = this.transform;
        if (!m) {
            return [
                1,
                1
            ];
        }
        var sx = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
        var sy = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
        if (m[0] &lt; 0) {
            sx = -sx;
        }
        if (m[3] &lt; 0) {
            sy = -sy;
        }
        return [
            sx,
            sy
        ];
    };
    /**
     * &#x53D8;&#x6362;&#x5750;&#x6807;&#x4F4D;&#x7F6E;&#x5230; shape &#x7684;&#x5C40;&#x90E8;&#x5750;&#x6807;&#x7A7A;&#x95F4;
     * @method
     * @param {number} x
     * @param {number} y
     * @return {Array.<number>}
     */
    transformableProto.transformCoordToLocal = function (x, y) {
        var v2 = [
                x,
                y
            ];
        var invTransform = this.invTransform;
        if (invTransform) {
            vector.applyTransform(v2, v2, invTransform);
        }
        return v2;
    };
    /**
     * &#x53D8;&#x6362;&#x5C40;&#x90E8;&#x5750;&#x6807;&#x4F4D;&#x7F6E;&#x5230;&#x5168;&#x5C40;&#x5750;&#x6807;&#x7A7A;&#x95F4;
     * @method
     * @param {number} x
     * @param {number} y
     * @return {Array.<number>}
     */
    transformableProto.transformCoordToGlobal = function (x, y) {
        var v2 = [
                x,
                y
            ];
        var transform = this.transform;
        if (transform) {
            vector.applyTransform(v2, v2, transform);
        }
        return v2;
    };
    return Transformable;
});
define(&apos;zrender/mixin/Animatable&apos;, [&apos;require&apos;, &apos;../animation/Animator&apos;, &apos;../core/util&apos;, &apos;../core/log&apos;], function (require) {
    &apos;use strict&apos;;
    var Animator = require(&apos;../animation/Animator&apos;);
    var util = require(&apos;../core/util&apos;);
    var isString = util.isString;
    var isFunction = util.isFunction;
    var isObject = util.isObject;
    var log = require(&apos;../core/log&apos;);
    /**
     * @alias modue:zrender/mixin/Animatable
     * @constructor
     */
    var Animatable = function () {
        /**
         * @type {Array.<module:zrender animation="" animator="">}
         * @readOnly
         */
        this.animators = [];
    };
    Animatable.prototype = {
        constructor: Animatable,
        animate: function (path, loop) {
            var target;
            var animatingShape = false;
            var el = this;
            var zr = this.__zr;
            if (path) {
                var pathSplitted = path.split(&apos;.&apos;);
                var prop = el;
                // If animating shape
                animatingShape = pathSplitted[0] === &apos;shape&apos;;
                for (var i = 0, l = pathSplitted.length; i &lt; l; i++) {
                    if (!prop) {
                        continue;
                    }
                    prop = prop[pathSplitted[i]];
                }
                if (prop) {
                    target = prop;
                }
            } else {
                target = el;
            }
            if (!target) {
                log(&apos;Property &quot;&apos; + path + &apos;&quot; is not existed in element &apos; + el.id);
                return;
            }
            var animators = el.animators;
            var animator = new Animator(target, loop);
            animator.during(function (target) {
                el.dirty(animatingShape);
            }).done(function () {
                // FIXME Animator will not be removed if use `Animator#stop` to stop animation
                animators.splice(util.indexOf(animators, animator), 1);
            });
            animators.push(animator);
            // If animate after added to the zrender
            if (zr) {
                zr.animation.addAnimator(animator);
            }
            return animator;
        },
        stopAnimation: function (forwardToLast) {
            var animators = this.animators;
            var len = animators.length;
            for (var i = 0; i &lt; len; i++) {
                animators[i].stop(forwardToLast);
            }
            animators.length = 0;
            return this;
        },
        animateTo: function (target, time, delay, easing, callback) {
            // animateTo(target, time, easing, callback);
            if (isString(delay)) {
                callback = easing;
                easing = delay;
                delay = 0;
            }    // animateTo(target, time, delay, callback);
            else if (isFunction(easing)) {
                callback = easing;
                easing = &apos;linear&apos;;
                delay = 0;
            }    // animateTo(target, time, callback);
            else if (isFunction(delay)) {
                callback = delay;
                delay = 0;
            }    // animateTo(target, callback)
            else if (isFunction(time)) {
                callback = time;
                time = 500;
            }    // animateTo(target)
            else if (!time) {
                time = 500;
            }
            // Stop all previous animations
            this.stopAnimation();
            this._animateToShallow(&apos;&apos;, this, target, time, delay, easing, callback);
            // Animators may be removed immediately after start
            // if there is nothing to animate
            var animators = this.animators.slice();
            var count = animators.length;
            function done() {
                count--;
                if (!count) {
                    callback &amp;&amp; callback();
                }
            }
            // No animators. This should be checked before animators[i].start(),
            // because &apos;done&apos; may be executed immediately if no need to animate.
            if (!count) {
                callback &amp;&amp; callback();
            }
            // Start after all animators created
            // Incase any animator is done immediately when all animation properties are not changed
            for (var i = 0; i &lt; animators.length; i++) {
                animators[i].done(done).start(easing);
            }
        },
        _animateToShallow: function (path, source, target, time, delay) {
            var objShallow = {};
            var propertyCount = 0;
            for (var name in target) {
                if (source[name] != null) {
                    if (isObject(target[name]) &amp;&amp; !util.isArrayLike(target[name])) {
                        this._animateToShallow(path ? path + &apos;.&apos; + name : name, source[name], target[name], time, delay);
                    } else {
                        objShallow[name] = target[name];
                        propertyCount++;
                    }
                } else if (target[name] != null) {
                    // Attr directly if not has property
                    // FIXME, if some property not needed for element ?
                    if (!path) {
                        this.attr(name, target[name]);
                    } else {
                        // Shape or style
                        var props = {};
                        props[path] = {};
                        props[path][name] = target[name];
                        this.attr(props);
                    }
                }
            }
            if (propertyCount &gt; 0) {
                this.animate(path, false).when(time == null ? 500 : time, objShallow).delay(delay || 0);
            }
            return this;
        }
    };
    return Animatable;
});
define(&apos;echarts/coord/axisDefault&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var defaultOption = {
            show: true,
            zlevel: 0,
            z: 0,
            inverse: false,
            name: &apos;&apos;,
            nameLocation: &apos;end&apos;,
            nameRotate: null,
            nameTruncate: {
                maxWidth: null,
                ellipsis: &apos;...&apos;,
                placeholder: &apos;.&apos;
            },
            nameTextStyle: {},
            nameGap: 15,
            silent: false,
            triggerEvent: false,
            tooltip: { show: false },
            axisLine: {
                show: true,
                onZero: true,
                lineStyle: {
                    color: &apos;#333&apos;,
                    width: 1,
                    type: &apos;solid&apos;
                }
            },
            axisTick: {
                show: true,
                inside: false,
                length: 5,
                lineStyle: { width: 1 }
            },
            axisLabel: {
                show: true,
                inside: false,
                rotate: 0,
                margin: 8,
                textStyle: { fontSize: 12 }
            },
            splitLine: {
                show: true,
                lineStyle: {
                    color: [&apos;#ccc&apos;],
                    width: 1,
                    type: &apos;solid&apos;
                }
            },
            splitArea: {
                show: false,
                areaStyle: {
                    color: [
                        &apos;rgba(250,250,250,0.3)&apos;,
                        &apos;rgba(200,200,200,0.3)&apos;
                    ]
                }
            }
        };
    var categoryAxis = zrUtil.merge({
            boundaryGap: true,
            splitLine: { show: false },
            axisTick: {
                alignWithLabel: false,
                interval: &apos;auto&apos;
            },
            axisLabel: { interval: &apos;auto&apos; }
        }, defaultOption);
    var valueAxis = zrUtil.merge({
            boundaryGap: [
                0,
                0
            ],
            splitNumber: 5
        }, defaultOption);
    // FIXME
    var timeAxis = zrUtil.defaults({
            scale: true,
            min: &apos;dataMin&apos;,
            max: &apos;dataMax&apos;
        }, valueAxis);
    var logAxis = zrUtil.defaults({}, valueAxis);
    logAxis.scale = true;
    return {
        categoryAxis: categoryAxis,
        valueAxis: valueAxis,
        timeAxis: timeAxis,
        logAxis: logAxis
    };
});
define(&apos;zrender/animation/Animator&apos;, [&apos;require&apos;, &apos;./Clip&apos;, &apos;../tool/color&apos;, &apos;../core/util&apos;], function (require) {
    var Clip = require(&apos;./Clip&apos;);
    var color = require(&apos;../tool/color&apos;);
    var util = require(&apos;../core/util&apos;);
    var isArrayLike = util.isArrayLike;
    var arraySlice = Array.prototype.slice;
    function defaultGetter(target, key) {
        return target[key];
    }
    function defaultSetter(target, key, value) {
        target[key] = value;
    }
    /**
     * @param  {number} p0
     * @param  {number} p1
     * @param  {number} percent
     * @return {number}
     */
    function interpolateNumber(p0, p1, percent) {
        return (p1 - p0) * percent + p0;
    }
    /**
     * @param  {string} p0
     * @param  {string} p1
     * @param  {number} percent
     * @return {string}
     */
    function interpolateString(p0, p1, percent) {
        return percent &gt; 0.5 ? p1 : p0;
    }
    /**
     * @param  {Array} p0
     * @param  {Array} p1
     * @param  {number} percent
     * @param  {Array} out
     * @param  {number} arrDim
     */
    function interpolateArray(p0, p1, percent, out, arrDim) {
        var len = p0.length;
        if (arrDim == 1) {
            for (var i = 0; i &lt; len; i++) {
                out[i] = interpolateNumber(p0[i], p1[i], percent);
            }
        } else {
            var len2 = p0[0].length;
            for (var i = 0; i &lt; len; i++) {
                for (var j = 0; j &lt; len2; j++) {
                    out[i][j] = interpolateNumber(p0[i][j], p1[i][j], percent);
                }
            }
        }
    }
    // arr0 is source array, arr1 is target array.
    // Do some preprocess to avoid error happened when interpolating from arr0 to arr1
    function fillArr(arr0, arr1, arrDim) {
        var arr0Len = arr0.length;
        var arr1Len = arr1.length;
        if (arr0Len !== arr1Len) {
            // FIXME Not work for TypedArray
            var isPreviousLarger = arr0Len &gt; arr1Len;
            if (isPreviousLarger) {
                // Cut the previous
                arr0.length = arr1Len;
            } else {
                // Fill the previous
                for (var i = arr0Len; i &lt; arr1Len; i++) {
                    arr0.push(arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i]));
                }
            }
        }
        // Handling NaN value
        var len2 = arr0[0] &amp;&amp; arr0[0].length;
        for (var i = 0; i &lt; arr0.length; i++) {
            if (arrDim === 1) {
                if (isNaN(arr0[i])) {
                    arr0[i] = arr1[i];
                }
            } else {
                for (var j = 0; j &lt; len2; j++) {
                    if (isNaN(arr0[i][j])) {
                        arr0[i][j] = arr1[i][j];
                    }
                }
            }
        }
    }
    /**
     * @param  {Array} arr0
     * @param  {Array} arr1
     * @param  {number} arrDim
     * @return {boolean}
     */
    function isArraySame(arr0, arr1, arrDim) {
        if (arr0 === arr1) {
            return true;
        }
        var len = arr0.length;
        if (len !== arr1.length) {
            return false;
        }
        if (arrDim === 1) {
            for (var i = 0; i &lt; len; i++) {
                if (arr0[i] !== arr1[i]) {
                    return false;
                }
            }
        } else {
            var len2 = arr0[0].length;
            for (var i = 0; i &lt; len; i++) {
                for (var j = 0; j &lt; len2; j++) {
                    if (arr0[i][j] !== arr1[i][j]) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
    /**
     * Catmull Rom interpolate array
     * @param  {Array} p0
     * @param  {Array} p1
     * @param  {Array} p2
     * @param  {Array} p3
     * @param  {number} t
     * @param  {number} t2
     * @param  {number} t3
     * @param  {Array} out
     * @param  {number} arrDim
     */
    function catmullRomInterpolateArray(p0, p1, p2, p3, t, t2, t3, out, arrDim) {
        var len = p0.length;
        if (arrDim == 1) {
            for (var i = 0; i &lt; len; i++) {
                out[i] = catmullRomInterpolate(p0[i], p1[i], p2[i], p3[i], t, t2, t3);
            }
        } else {
            var len2 = p0[0].length;
            for (var i = 0; i &lt; len; i++) {
                for (var j = 0; j &lt; len2; j++) {
                    out[i][j] = catmullRomInterpolate(p0[i][j], p1[i][j], p2[i][j], p3[i][j], t, t2, t3);
                }
            }
        }
    }
    /**
     * Catmull Rom interpolate number
     * @param  {number} p0
     * @param  {number} p1
     * @param  {number} p2
     * @param  {number} p3
     * @param  {number} t
     * @param  {number} t2
     * @param  {number} t3
     * @return {number}
     */
    function catmullRomInterpolate(p0, p1, p2, p3, t, t2, t3) {
        var v0 = (p2 - p0) * 0.5;
        var v1 = (p3 - p1) * 0.5;
        return (2 * (p1 - p2) + v0 + v1) * t3 + (-3 * (p1 - p2) - 2 * v0 - v1) * t2 + v0 * t + p1;
    }
    function cloneValue(value) {
        if (isArrayLike(value)) {
            var len = value.length;
            if (isArrayLike(value[0])) {
                var ret = [];
                for (var i = 0; i &lt; len; i++) {
                    ret.push(arraySlice.call(value[i]));
                }
                return ret;
            }
            return arraySlice.call(value);
        }
        return value;
    }
    function rgba2String(rgba) {
        rgba[0] = Math.floor(rgba[0]);
        rgba[1] = Math.floor(rgba[1]);
        rgba[2] = Math.floor(rgba[2]);
        return &apos;rgba(&apos; + rgba.join(&apos;,&apos;) + &apos;)&apos;;
    }
    function createTrackClip(animator, easing, oneTrackDone, keyframes, propName) {
        var getter = animator._getter;
        var setter = animator._setter;
        var useSpline = easing === &apos;spline&apos;;
        var trackLen = keyframes.length;
        if (!trackLen) {
            return;
        }
        // Guess data type
        var firstVal = keyframes[0].value;
        var isValueArray = isArrayLike(firstVal);
        var isValueColor = false;
        var isValueString = false;
        // For vertices morphing
        var arrDim = isValueArray &amp;&amp; isArrayLike(firstVal[0]) ? 2 : 1;
        var trackMaxTime;
        // Sort keyframe as ascending
        keyframes.sort(function (a, b) {
            return a.time - b.time;
        });
        trackMaxTime = keyframes[trackLen - 1].time;
        // Percents of each keyframe
        var kfPercents = [];
        // Value of each keyframe
        var kfValues = [];
        var prevValue = keyframes[0].value;
        var isAllValueEqual = true;
        for (var i = 0; i &lt; trackLen; i++) {
            kfPercents.push(keyframes[i].time / trackMaxTime);
            // Assume value is a color when it is a string
            var value = keyframes[i].value;
            // Check if value is equal, deep check if value is array
            if (!(isValueArray &amp;&amp; isArraySame(value, prevValue, arrDim) || !isValueArray &amp;&amp; value === prevValue)) {
                isAllValueEqual = false;
            }
            prevValue = value;
            // Try converting a string to a color array
            if (typeof value == &apos;string&apos;) {
                var colorArray = color.parse(value);
                if (colorArray) {
                    value = colorArray;
                    isValueColor = true;
                } else {
                    isValueString = true;
                }
            }
            kfValues.push(value);
        }
        if (isAllValueEqual) {
            return;
        }
        var lastValue = kfValues[trackLen - 1];
        // Polyfill array and NaN value
        for (var i = 0; i &lt; trackLen - 1; i++) {
            if (isValueArray) {
                fillArr(kfValues[i], lastValue, arrDim);
            } else {
                if (isNaN(kfValues[i]) &amp;&amp; !isNaN(lastValue) &amp;&amp; !isValueString &amp;&amp; !isValueColor) {
                    kfValues[i] = lastValue;
                }
            }
        }
        isValueArray &amp;&amp; fillArr(getter(animator._target, propName), lastValue, arrDim);
        // Cache the key of last frame to speed up when
        // animation playback is sequency
        var lastFrame = 0;
        var lastFramePercent = 0;
        var start;
        var w;
        var p0;
        var p1;
        var p2;
        var p3;
        if (isValueColor) {
            var rgba = [
                    0,
                    0,
                    0,
                    0
                ];
        }
        var onframe = function (target, percent) {
            // Find the range keyframes
            // kf1-----kf2---------current--------kf3
            // find kf2 and kf3 and do interpolation
            var frame;
            if (percent &lt; lastFramePercent) {
                // Start from next key
                // PENDING start from lastFrame ?
                start = Math.min(lastFrame + 1, trackLen - 1);
                for (frame = start; frame &gt;= 0; frame--) {
                    if (kfPercents[frame] <= percent)="" {="" break;="" }="" pending="" really="" need="" to="" do="" this="" ?="" frame="Math.min(frame," tracklen="" -="" 2);="" else="" for="" (frame="lastFrame;" <="" tracklen;="" frame++)="" if="" (kfpercents[frame]=""> percent) {
                        break;
                    }
                }
                frame = Math.min(frame - 1, trackLen - 2);
            }
            lastFrame = frame;
            lastFramePercent = percent;
            var range = kfPercents[frame + 1] - kfPercents[frame];
            if (range === 0) {
                return;
            } else {
                w = (percent - kfPercents[frame]) / range;
            }
            if (useSpline) {
                p1 = kfValues[frame];
                p0 = kfValues[frame === 0 ? frame : frame - 1];
                p2 = kfValues[frame &gt; trackLen - 2 ? trackLen - 1 : frame + 1];
                p3 = kfValues[frame &gt; trackLen - 3 ? trackLen - 1 : frame + 2];
                if (isValueArray) {
                    catmullRomInterpolateArray(p0, p1, p2, p3, w, w * w, w * w * w, getter(target, propName), arrDim);
                } else {
                    var value;
                    if (isValueColor) {
                        value = catmullRomInterpolateArray(p0, p1, p2, p3, w, w * w, w * w * w, rgba, 1);
                        value = rgba2String(rgba);
                    } else if (isValueString) {
                        // String is step(0.5)
                        return interpolateString(p1, p2, w);
                    } else {
                        value = catmullRomInterpolate(p0, p1, p2, p3, w, w * w, w * w * w);
                    }
                    setter(target, propName, value);
                }
            } else {
                if (isValueArray) {
                    interpolateArray(kfValues[frame], kfValues[frame + 1], w, getter(target, propName), arrDim);
                } else {
                    var value;
                    if (isValueColor) {
                        interpolateArray(kfValues[frame], kfValues[frame + 1], w, rgba, 1);
                        value = rgba2String(rgba);
                    } else if (isValueString) {
                        // String is step(0.5)
                        return interpolateString(kfValues[frame], kfValues[frame + 1], w);
                    } else {
                        value = interpolateNumber(kfValues[frame], kfValues[frame + 1], w);
                    }
                    setter(target, propName, value);
                }
            }
        };
        var clip = new Clip({
                target: animator._target,
                life: trackMaxTime,
                loop: animator._loop,
                delay: animator._delay,
                onframe: onframe,
                ondestroy: oneTrackDone
            });
        if (easing &amp;&amp; easing !== &apos;spline&apos;) {
            clip.easing = easing;
        }
        return clip;
    }
    /**
     * @alias module:zrender/animation/Animator
     * @constructor
     * @param {Object} target
     * @param {boolean} loop
     * @param {Function} getter
     * @param {Function} setter
     */
    var Animator = function (target, loop, getter, setter) {
        this._tracks = {};
        this._target = target;
        this._loop = loop || false;
        this._getter = getter || defaultGetter;
        this._setter = setter || defaultSetter;
        this._clipCount = 0;
        this._delay = 0;
        this._doneList = [];
        this._onframeList = [];
        this._clipList = [];
    };
    Animator.prototype = {
        when: function (time, props) {
            var tracks = this._tracks;
            for (var propName in props) {
                if (!tracks[propName]) {
                    tracks[propName] = [];
                    // Invalid value
                    var value = this._getter(this._target, propName);
                    if (value == null) {
                        // zrLog(&apos;Invalid property &apos; + propName);
                        continue;
                    }
                    // If time is 0
                    //  Then props is given initialize value
                    // Else
                    //  Initialize value from current prop value
                    if (time !== 0) {
                        tracks[propName].push({
                            time: 0,
                            value: cloneValue(value)
                        });
                    }
                }
                tracks[propName].push({
                    time: time,
                    value: props[propName]
                });
            }
            return this;
        },
        during: function (callback) {
            this._onframeList.push(callback);
            return this;
        },
        _doneCallback: function () {
            // Clear all tracks
            this._tracks = {};
            // Clear all clips
            this._clipList.length = 0;
            var doneList = this._doneList;
            var len = doneList.length;
            for (var i = 0; i &lt; len; i++) {
                doneList[i].call(this);
            }
        },
        start: function (easing) {
            var self = this;
            var clipCount = 0;
            var oneTrackDone = function () {
                clipCount--;
                if (!clipCount) {
                    self._doneCallback();
                }
            };
            var lastClip;
            for (var propName in this._tracks) {
                var clip = createTrackClip(this, easing, oneTrackDone, this._tracks[propName], propName);
                if (clip) {
                    this._clipList.push(clip);
                    clipCount++;
                    // If start after added to animation
                    if (this.animation) {
                        this.animation.addClip(clip);
                    }
                    lastClip = clip;
                }
            }
            // Add during callback on the last clip
            if (lastClip) {
                var oldOnFrame = lastClip.onframe;
                lastClip.onframe = function (target, percent) {
                    oldOnFrame(target, percent);
                    for (var i = 0; i &lt; self._onframeList.length; i++) {
                        self._onframeList[i](target, percent);
                    }
                };
            }
            if (!clipCount) {
                this._doneCallback();
            }
            return this;
        },
        stop: function (forwardToLast) {
            var clipList = this._clipList;
            var animation = this.animation;
            for (var i = 0; i &lt; clipList.length; i++) {
                var clip = clipList[i];
                if (forwardToLast) {
                    // Move to last frame before stop
                    clip.onframe(this._target, 1);
                }
                animation &amp;&amp; animation.removeClip(clip);
            }
            clipList.length = 0;
        },
        delay: function (time) {
            this._delay = time;
            return this;
        },
        done: function (cb) {
            if (cb) {
                this._doneList.push(cb);
            }
            return this;
        },
        getClips: function () {
            return this._clipList;
        }
    };
    return Animator;
});
define(&apos;zrender/core/log&apos;, [&apos;require&apos;, &apos;../config&apos;], function (require) {
    var config = require(&apos;../config&apos;);
    /**
         * @exports zrender/tool/log
         * @author Kener (@Kener-&#x6797;&#x5CF0;, kener.linfeng@gmail.com)
         */
    return function () {
        if (config.debugMode === 0) {
            return;
        } else if (config.debugMode == 1) {
            for (var k in arguments) {
                throw new Error(arguments[k]);
            }
        } else if (config.debugMode &gt; 1) {
            for (var k in arguments) {
                console.log(arguments[k]);
            }
        }
    };    /* for debug
        return function(mes) {
            document.getElementById(&apos;wrong-message&apos;).innerHTML =
                mes + &apos; &apos; + (new Date() - 0)
                + &apos;<br>&apos; 
                + document.getElementById(&apos;wrong-message&apos;).innerHTML;
        };
        */
});
define(&apos;zrender/animation/Clip&apos;, [&apos;require&apos;, &apos;./easing&apos;], function (require) {
    var easingFuncs = require(&apos;./easing&apos;);
    function Clip(options) {
        this._target = options.target;
        // &#x751F;&#x547D;&#x5468;&#x671F;
        this._life = options.life || 1000;
        // &#x5EF6;&#x65F6;
        this._delay = options.delay || 0;
        // &#x5F00;&#x59CB;&#x65F6;&#x95F4;
        // this._startTime = new Date().getTime() + this._delay;// &#x5355;&#x4F4D;&#x6BEB;&#x79D2;
        this._initialized = false;
        // &#x662F;&#x5426;&#x5FAA;&#x73AF;
        this.loop = options.loop == null ? false : options.loop;
        this.gap = options.gap || 0;
        this.easing = options.easing || &apos;Linear&apos;;
        this.onframe = options.onframe;
        this.ondestroy = options.ondestroy;
        this.onrestart = options.onrestart;
    }
    Clip.prototype = {
        constructor: Clip,
        step: function (time) {
            // Set startTime on first step, or _startTime may has milleseconds different between clips
            // PENDING
            if (!this._initialized) {
                this._startTime = new Date().getTime() + this._delay;
                this._initialized = true;
            }
            var percent = (time - this._startTime) / this._life;
            // &#x8FD8;&#x6CA1;&#x5F00;&#x59CB;
            if (percent &lt; 0) {
                return;
            }
            percent = Math.min(percent, 1);
            var easing = this.easing;
            var easingFunc = typeof easing == &apos;string&apos; ? easingFuncs[easing] : easing;
            var schedule = typeof easingFunc === &apos;function&apos; ? easingFunc(percent) : percent;
            this.fire(&apos;frame&apos;, schedule);
            // &#x7ED3;&#x675F;
            if (percent == 1) {
                if (this.loop) {
                    this.restart();
                    // &#x91CD;&#x65B0;&#x5F00;&#x59CB;&#x5468;&#x671F;
                    // &#x629B;&#x51FA;&#x800C;&#x4E0D;&#x662F;&#x76F4;&#x63A5;&#x8C03;&#x7528;&#x4E8B;&#x4EF6;&#x76F4;&#x5230; stage.update &#x540E;&#x518D;&#x7EDF;&#x4E00;&#x8C03;&#x7528;&#x8FD9;&#x4E9B;&#x4E8B;&#x4EF6;
                    return &apos;restart&apos;;
                }
                // &#x52A8;&#x753B;&#x5B8C;&#x6210;&#x5C06;&#x8FD9;&#x4E2A;&#x63A7;&#x5236;&#x5668;&#x6807;&#x8BC6;&#x4E3A;&#x5F85;&#x5220;&#x9664;
                // &#x5728;Animation.update&#x4E2D;&#x8FDB;&#x884C;&#x6279;&#x91CF;&#x5220;&#x9664;
                this._needsRemove = true;
                return &apos;destroy&apos;;
            }
            return null;
        },
        restart: function () {
            var time = new Date().getTime();
            var remainder = (time - this._startTime) % this._life;
            this._startTime = new Date().getTime() - remainder + this.gap;
            this._needsRemove = false;
        },
        fire: function (eventType, arg) {
            eventType = &apos;on&apos; + eventType;
            if (this[eventType]) {
                this[eventType](this._target, arg);
            }
        }
    };
    return Clip;
});
define(&apos;zrender/animation/easing&apos;, [], function () {
    var easing = {
            linear: function (k) {
                return k;
            },
            quadraticIn: function (k) {
                return k * k;
            },
            quadraticOut: function (k) {
                return k * (2 - k);
            },
            quadraticInOut: function (k) {
                if ((k *= 2) &lt; 1) {
                    return 0.5 * k * k;
                }
                return -0.5 * (--k * (k - 2) - 1);
            },
            cubicIn: function (k) {
                return k * k * k;
            },
            cubicOut: function (k) {
                return --k * k * k + 1;
            },
            cubicInOut: function (k) {
                if ((k *= 2) &lt; 1) {
                    return 0.5 * k * k * k;
                }
                return 0.5 * ((k -= 2) * k * k + 2);
            },
            quarticIn: function (k) {
                return k * k * k * k;
            },
            quarticOut: function (k) {
                return 1 - --k * k * k * k;
            },
            quarticInOut: function (k) {
                if ((k *= 2) &lt; 1) {
                    return 0.5 * k * k * k * k;
                }
                return -0.5 * ((k -= 2) * k * k * k - 2);
            },
            quinticIn: function (k) {
                return k * k * k * k * k;
            },
            quinticOut: function (k) {
                return --k * k * k * k * k + 1;
            },
            quinticInOut: function (k) {
                if ((k *= 2) &lt; 1) {
                    return 0.5 * k * k * k * k * k;
                }
                return 0.5 * ((k -= 2) * k * k * k * k + 2);
            },
            sinusoidalIn: function (k) {
                return 1 - Math.cos(k * Math.PI / 2);
            },
            sinusoidalOut: function (k) {
                return Math.sin(k * Math.PI / 2);
            },
            sinusoidalInOut: function (k) {
                return 0.5 * (1 - Math.cos(Math.PI * k));
            },
            exponentialIn: function (k) {
                return k === 0 ? 0 : Math.pow(1024, k - 1);
            },
            exponentialOut: function (k) {
                return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
            },
            exponentialInOut: function (k) {
                if (k === 0) {
                    return 0;
                }
                if (k === 1) {
                    return 1;
                }
                if ((k *= 2) &lt; 1) {
                    return 0.5 * Math.pow(1024, k - 1);
                }
                return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
            },
            circularIn: function (k) {
                return 1 - Math.sqrt(1 - k * k);
            },
            circularOut: function (k) {
                return Math.sqrt(1 - --k * k);
            },
            circularInOut: function (k) {
                if ((k *= 2) &lt; 1) {
                    return -0.5 * (Math.sqrt(1 - k * k) - 1);
                }
                return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
            },
            elasticIn: function (k) {
                var s;
                var a = 0.1;
                var p = 0.4;
                if (k === 0) {
                    return 0;
                }
                if (k === 1) {
                    return 1;
                }
                if (!a || a &lt; 1) {
                    a = 1;
                    s = p / 4;
                } else {
                    s = p * Math.asin(1 / a) / (2 * Math.PI);
                }
                return -(a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
            },
            elasticOut: function (k) {
                var s;
                var a = 0.1;
                var p = 0.4;
                if (k === 0) {
                    return 0;
                }
                if (k === 1) {
                    return 1;
                }
                if (!a || a &lt; 1) {
                    a = 1;
                    s = p / 4;
                } else {
                    s = p * Math.asin(1 / a) / (2 * Math.PI);
                }
                return a * Math.pow(2, -10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1;
            },
            elasticInOut: function (k) {
                var s;
                var a = 0.1;
                var p = 0.4;
                if (k === 0) {
                    return 0;
                }
                if (k === 1) {
                    return 1;
                }
                if (!a || a &lt; 1) {
                    a = 1;
                    s = p / 4;
                } else {
                    s = p * Math.asin(1 / a) / (2 * Math.PI);
                }
                if ((k *= 2) &lt; 1) {
                    return -0.5 * (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
                }
                return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;
            },
            backIn: function (k) {
                var s = 1.70158;
                return k * k * ((s + 1) * k - s);
            },
            backOut: function (k) {
                var s = 1.70158;
                return --k * k * ((s + 1) * k + s) + 1;
            },
            backInOut: function (k) {
                var s = 1.70158 * 1.525;
                if ((k *= 2) &lt; 1) {
                    return 0.5 * (k * k * ((s + 1) * k - s));
                }
                return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
            },
            bounceIn: function (k) {
                return 1 - easing.bounceOut(1 - k);
            },
            bounceOut: function (k) {
                if (k &lt; 1 / 2.75) {
                    return 7.5625 * k * k;
                } else if (k &lt; 2 / 2.75) {
                    return 7.5625 * (k -= 1.5 / 2.75) * k + 0.75;
                } else if (k &lt; 2.5 / 2.75) {
                    return 7.5625 * (k -= 2.25 / 2.75) * k + 0.9375;
                } else {
                    return 7.5625 * (k -= 2.625 / 2.75) * k + 0.984375;
                }
            },
            bounceInOut: function (k) {
                if (k &lt; 0.5) {
                    return easing.bounceIn(k * 2) * 0.5;
                }
                return easing.bounceOut(k * 2 - 1) * 0.5 + 0.5;
            }
        };
    return easing;
});
define(&apos;zrender/config&apos;, [], function () {
    var dpr = 1;
    // If in browser environment
    if (typeof window !== &apos;undefined&apos;) {
        dpr = Math.max(window.devicePixelRatio || 1, 1);
    }
    /**
     * config&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;&#x9879;
     * @exports zrender/config
     * @author Kener (@Kener-&#x6797;&#x5CF0;, kener.linfeng@gmail.com)
     */
    var config = {
            debugMode: 0,
            devicePixelRatio: dpr
        };
    return config;
});
define(&apos;zrender/graphic/shape/Circle&apos;, [&apos;require&apos;, &apos;../Path&apos;], function (require) {
    &apos;use strict&apos;;
    return require(&apos;../Path&apos;).extend({
        type: &apos;circle&apos;,
        shape: {
            cx: 0,
            cy: 0,
            r: 0
        },
        buildPath: function (ctx, shape, inBundle) {
            // Better stroking in ShapeBundle
            // Always do it may have performence issue ( fill may be 2x more cost)
            if (inBundle) {
                ctx.moveTo(shape.cx + shape.r, shape.cy);
            }
            // Better stroking in ShapeBundle
            // ctx.moveTo(shape.cx + shape.r, shape.cy);
            ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2, true);
        }
    });
});
define(&apos;zrender/graphic/Path&apos;, [&apos;require&apos;, &apos;./Displayable&apos;, &apos;../core/util&apos;, &apos;../core/PathProxy&apos;, &apos;../contain/path&apos;, &apos;./Pattern&apos;], function (require) {
    var Displayable = require(&apos;./Displayable&apos;);
    var zrUtil = require(&apos;../core/util&apos;);
    var PathProxy = require(&apos;../core/PathProxy&apos;);
    var pathContain = require(&apos;../contain/path&apos;);
    var Pattern = require(&apos;./Pattern&apos;);
    var getCanvasPattern = Pattern.prototype.getCanvasPattern;
    var abs = Math.abs;
    /**
     * @alias module:zrender/graphic/Path
     * @extends module:zrender/graphic/Displayable
     * @constructor
     * @param {Object} opts
     */
    function Path(opts) {
        Displayable.call(this, opts);
        /**
         * @type {module:zrender/core/PathProxy}
         * @readOnly
         */
        this.path = new PathProxy();
    }
    Path.prototype = {
        constructor: Path,
        type: &apos;path&apos;,
        __dirtyPath: true,
        strokeContainThreshold: 5,
        brush: function (ctx, prevEl) {
            var style = this.style;
            var path = this.path;
            var hasStroke = style.hasStroke();
            var hasFill = style.hasFill();
            var fill = style.fill;
            var stroke = style.stroke;
            var hasFillGradient = hasFill &amp;&amp; !!fill.colorStops;
            var hasStrokeGradient = hasStroke &amp;&amp; !!stroke.colorStops;
            var hasFillPattern = hasFill &amp;&amp; !!fill.image;
            var hasStrokePattern = hasStroke &amp;&amp; !!stroke.image;
            style.bind(ctx, this, prevEl);
            this.setTransform(ctx);
            if (this.__dirty) {
                var rect = this.getBoundingRect();
                // Update gradient because bounding rect may changed
                if (hasFillGradient) {
                    this._fillGradient = style.getGradient(ctx, fill, rect);
                }
                if (hasStrokeGradient) {
                    this._strokeGradient = style.getGradient(ctx, stroke, rect);
                }
            }
            // Use the gradient or pattern
            if (hasFillGradient) {
                // PENDING If may have affect the state
                ctx.fillStyle = this._fillGradient;
            } else if (hasFillPattern) {
                ctx.fillStyle = getCanvasPattern.call(fill, ctx);
            }
            if (hasStrokeGradient) {
                ctx.strokeStyle = this._strokeGradient;
            } else if (hasStrokePattern) {
                ctx.strokeStyle = getCanvasPattern.call(stroke, ctx);
            }
            var lineDash = style.lineDash;
            var lineDashOffset = style.lineDashOffset;
            var ctxLineDash = !!ctx.setLineDash;
            // Update path sx, sy
            var scale = this.getGlobalScale();
            path.setScale(scale[0], scale[1]);
            // Proxy context
            // Rebuild path in following 2 cases
            // 1. Path is dirty
            // 2. Path needs javascript implemented lineDash stroking.
            //    In this case, lineDash information will not be saved in PathProxy
            if (this.__dirtyPath || lineDash &amp;&amp; !ctxLineDash &amp;&amp; hasStroke) {
                path = this.path.beginPath(ctx);
                // Setting line dash before build path
                if (lineDash &amp;&amp; !ctxLineDash) {
                    path.setLineDash(lineDash);
                    path.setLineDashOffset(lineDashOffset);
                }
                this.buildPath(path, this.shape, false);
                // Clear path dirty flag
                this.__dirtyPath = false;
            } else {
                // Replay path building
                ctx.beginPath();
                this.path.rebuildPath(ctx);
            }
            hasFill &amp;&amp; path.fill(ctx);
            if (lineDash &amp;&amp; ctxLineDash) {
                ctx.setLineDash(lineDash);
                ctx.lineDashOffset = lineDashOffset;
            }
            hasStroke &amp;&amp; path.stroke(ctx);
            if (lineDash &amp;&amp; ctxLineDash) {
                // PENDING
                // Remove lineDash
                ctx.setLineDash([]);
            }
            this.restoreTransform(ctx);
            // Draw rect text
            if (style.text || style.text === 0) {
                // var rect = this.getBoundingRect();
                this.drawRectText(ctx, this.getBoundingRect());
            }
        },
        buildPath: function (ctx, shapeCfg, inBundle) {
        },
        getBoundingRect: function () {
            var rect = this._rect;
            var style = this.style;
            var needsUpdateRect = !rect;
            if (needsUpdateRect) {
                var path = this.path;
                if (this.__dirtyPath) {
                    path.beginPath();
                    this.buildPath(path, this.shape, false);
                }
                rect = path.getBoundingRect();
            }
            this._rect = rect;
            if (style.hasStroke()) {
                // Needs update rect with stroke lineWidth when
                // 1. Element changes scale or lineWidth
                // 2. Shape is changed
                var rectWithStroke = this._rectWithStroke || (this._rectWithStroke = rect.clone());
                if (this.__dirty || needsUpdateRect) {
                    rectWithStroke.copy(rect);
                    // FIXME Must after updateTransform
                    var w = style.lineWidth;
                    // PENDING, Min line width is needed when line is horizontal or vertical
                    var lineScale = style.strokeNoScale ? this.getLineScale() : 1;
                    // Only add extra hover lineWidth when there are no fill
                    if (!style.hasFill()) {
                        w = Math.max(w, this.strokeContainThreshold || 4);
                    }
                    // Consider line width
                    // Line scale can&apos;t be 0;
                    if (lineScale &gt; 1e-10) {
                        rectWithStroke.width += w / lineScale;
                        rectWithStroke.height += w / lineScale;
                        rectWithStroke.x -= w / lineScale / 2;
                        rectWithStroke.y -= w / lineScale / 2;
                    }
                }
                // Return rect with stroke
                return rectWithStroke;
            }
            return rect;
        },
        contain: function (x, y) {
            var localPos = this.transformCoordToLocal(x, y);
            var rect = this.getBoundingRect();
            var style = this.style;
            x = localPos[0];
            y = localPos[1];
            if (rect.contain(x, y)) {
                var pathData = this.path.data;
                if (style.hasStroke()) {
                    var lineWidth = style.lineWidth;
                    var lineScale = style.strokeNoScale ? this.getLineScale() : 1;
                    // Line scale can&apos;t be 0;
                    if (lineScale &gt; 1e-10) {
                        // Only add extra hover lineWidth when there are no fill
                        if (!style.hasFill()) {
                            lineWidth = Math.max(lineWidth, this.strokeContainThreshold);
                        }
                        if (pathContain.containStroke(pathData, lineWidth / lineScale, x, y)) {
                            return true;
                        }
                    }
                }
                if (style.hasFill()) {
                    return pathContain.contain(pathData, x, y);
                }
            }
            return false;
        },
        dirty: function (dirtyPath) {
            if (dirtyPath == null) {
                dirtyPath = true;
            }
            // Only mark dirty, not mark clean
            if (dirtyPath) {
                this.__dirtyPath = dirtyPath;
                this._rect = null;
            }
            this.__dirty = true;
            this.__zr &amp;&amp; this.__zr.refresh();
            // Used as a clipping path
            if (this.__clipTarget) {
                this.__clipTarget.dirty();
            }
        },
        animateShape: function (loop) {
            return this.animate(&apos;shape&apos;, loop);
        },
        attrKV: function (key, value) {
            // FIXME
            if (key === &apos;shape&apos;) {
                this.setShape(value);
                this.__dirtyPath = true;
                this._rect = null;
            } else {
                Displayable.prototype.attrKV.call(this, key, value);
            }
        },
        setShape: function (key, value) {
            var shape = this.shape;
            // Path from string may not have shape
            if (shape) {
                if (zrUtil.isObject(key)) {
                    for (var name in key) {
                        shape[name] = key[name];
                    }
                } else {
                    shape[key] = value;
                }
                this.dirty(true);
            }
            return this;
        },
        getLineScale: function () {
            var m = this.transform;
            // Get the line scale.
            // Determinant of `m` means how much the area is enlarged by the
            // transformation. So its square root can be used as a scale factor
            // for width.
            return m &amp;&amp; abs(m[0] - 1) &gt; 1e-10 &amp;&amp; abs(m[3] - 1) &gt; 1e-10 ? Math.sqrt(abs(m[0] * m[3] - m[2] * m[1])) : 1;
        }
    };
    /**
     * &#x6269;&#x5C55;&#x4E00;&#x4E2A; Path element, &#x6BD4;&#x5982;&#x661F;&#x5F62;&#xFF0C;&#x5706;&#x7B49;&#x3002;
     * Extend a path element
     * @param {Object} props
     * @param {string} props.type Path type
     * @param {Function} props.init Initialize
     * @param {Function} props.buildPath Overwrite buildPath method
     * @param {Object} [props.style] Extended default style config
     * @param {Object} [props.shape] Extended default shape config
     */
    Path.extend = function (defaults) {
        var Sub = function (opts) {
            Path.call(this, opts);
            if (defaults.style) {
                // Extend default style
                this.style.extendFrom(defaults.style, false);
            }
            // Extend default shape
            var defaultShape = defaults.shape;
            if (defaultShape) {
                this.shape = this.shape || {};
                var thisShape = this.shape;
                for (var name in defaultShape) {
                    if (!thisShape.hasOwnProperty(name) &amp;&amp; defaultShape.hasOwnProperty(name)) {
                        thisShape[name] = defaultShape[name];
                    }
                }
            }
            defaults.init &amp;&amp; defaults.init.call(this, opts);
        };
        zrUtil.inherits(Sub, Path);
        // FIXME &#x4E0D;&#x80FD; extend position, rotation &#x7B49;&#x5F15;&#x7528;&#x5BF9;&#x8C61;
        for (var name in defaults) {
            // Extending prototype values and methods
            if (name !== &apos;style&apos; &amp;&amp; name !== &apos;shape&apos;) {
                Sub.prototype[name] = defaults[name];
            }
        }
        return Sub;
    };
    zrUtil.inherits(Path, Displayable);
    return Path;
});
define(&apos;zrender/graphic/Gradient&apos;, [&apos;require&apos;], function (require) {
    /**
     * @param {Array.<object>} colorStops
     */
    var Gradient = function (colorStops) {
        this.colorStops = colorStops || [];
    };
    Gradient.prototype = {
        constructor: Gradient,
        addColorStop: function (offset, color) {
            this.colorStops.push({
                offset: offset,
                color: color
            });
        }
    };
    return Gradient;
});
define(&apos;zrender/tool/path&apos;, [&apos;require&apos;, &apos;../graphic/Path&apos;, &apos;../core/PathProxy&apos;, &apos;./transformPath&apos;, &apos;../core/matrix&apos;], function (require) {
    var Path = require(&apos;../graphic/Path&apos;);
    var PathProxy = require(&apos;../core/PathProxy&apos;);
    var transformPath = require(&apos;./transformPath&apos;);
    var matrix = require(&apos;../core/matrix&apos;);
    // command chars
    var cc = [
            &apos;m&apos;,
            &apos;M&apos;,
            &apos;l&apos;,
            &apos;L&apos;,
            &apos;v&apos;,
            &apos;V&apos;,
            &apos;h&apos;,
            &apos;H&apos;,
            &apos;z&apos;,
            &apos;Z&apos;,
            &apos;c&apos;,
            &apos;C&apos;,
            &apos;q&apos;,
            &apos;Q&apos;,
            &apos;t&apos;,
            &apos;T&apos;,
            &apos;s&apos;,
            &apos;S&apos;,
            &apos;a&apos;,
            &apos;A&apos;
        ];
    var mathSqrt = Math.sqrt;
    var mathSin = Math.sin;
    var mathCos = Math.cos;
    var PI = Math.PI;
    var vMag = function (v) {
        return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
    };
    var vRatio = function (u, v) {
        return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v));
    };
    var vAngle = function (u, v) {
        return (u[0] * v[1] &lt; u[1] * v[0] ? -1 : 1) * Math.acos(vRatio(u, v));
    };
    function processArc(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg, cmd, path) {
        var psi = psiDeg * (PI / 180);
        var xp = mathCos(psi) * (x1 - x2) / 2 + mathSin(psi) * (y1 - y2) / 2;
        var yp = -1 * mathSin(psi) * (x1 - x2) / 2 + mathCos(psi) * (y1 - y2) / 2;
        var lambda = xp * xp / (rx * rx) + yp * yp / (ry * ry);
        if (lambda &gt; 1) {
            rx *= mathSqrt(lambda);
            ry *= mathSqrt(lambda);
        }
        var f = (fa === fs ? -1 : 1) * mathSqrt((rx * rx * (ry * ry) - rx * rx * (yp * yp) - ry * ry * (xp * xp)) / (rx * rx * (yp * yp) + ry * ry * (xp * xp))) || 0;
        var cxp = f * rx * yp / ry;
        var cyp = f * -ry * xp / rx;
        var cx = (x1 + x2) / 2 + mathCos(psi) * cxp - mathSin(psi) * cyp;
        var cy = (y1 + y2) / 2 + mathSin(psi) * cxp + mathCos(psi) * cyp;
        var theta = vAngle([
                1,
                0
            ], [
                (xp - cxp) / rx,
                (yp - cyp) / ry
            ]);
        var u = [
                (xp - cxp) / rx,
                (yp - cyp) / ry
            ];
        var v = [
                (-1 * xp - cxp) / rx,
                (-1 * yp - cyp) / ry
            ];
        var dTheta = vAngle(u, v);
        if (vRatio(u, v) <= -1)="" {="" dtheta="PI;" }="" if="" (vratio(u,="" v)="">= 1) {
            dTheta = 0;
        }
        if (fs === 0 &amp;&amp; dTheta &gt; 0) {
            dTheta = dTheta - 2 * PI;
        }
        if (fs === 1 &amp;&amp; dTheta &lt; 0) {
            dTheta = dTheta + 2 * PI;
        }
        path.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs);
    }
    function createPathProxyFromString(data) {
        if (!data) {
            return [];
        }
        // command string
        var cs = data.replace(/-/g, &apos; -&apos;).replace(/  /g, &apos; &apos;).replace(/ /g, &apos;,&apos;).replace(/,,/g, &apos;,&apos;);
        var n;
        // create pipes so that we can split the data
        for (n = 0; n &lt; cc.length; n++) {
            cs = cs.replace(new RegExp(cc[n], &apos;g&apos;), &apos;|&apos; + cc[n]);
        }
        // create array
        var arr = cs.split(&apos;|&apos;);
        // init context point
        var cpx = 0;
        var cpy = 0;
        var path = new PathProxy();
        var CMD = PathProxy.CMD;
        var prevCmd;
        for (n = 1; n &lt; arr.length; n++) {
            var str = arr[n];
            var c = str.charAt(0);
            var off = 0;
            var p = str.slice(1).replace(/e,-/g, &apos;e-&apos;).split(&apos;,&apos;);
            var cmd;
            if (p.length &gt; 0 &amp;&amp; p[0] === &apos;&apos;) {
                p.shift();
            }
            for (var i = 0; i &lt; p.length; i++) {
                p[i] = parseFloat(p[i]);
            }
            while (off &lt; p.length &amp;&amp; !isNaN(p[off])) {
                if (isNaN(p[0])) {
                    break;
                }
                var ctlPtx;
                var ctlPty;
                var rx;
                var ry;
                var psi;
                var fa;
                var fs;
                var x1 = cpx;
                var y1 = cpy;
                // convert l, H, h, V, and v to L
                switch (c) {
                case &apos;l&apos;:
                    cpx += p[off++];
                    cpy += p[off++];
                    cmd = CMD.L;
                    path.addData(cmd, cpx, cpy);
                    break;
                case &apos;L&apos;:
                    cpx = p[off++];
                    cpy = p[off++];
                    cmd = CMD.L;
                    path.addData(cmd, cpx, cpy);
                    break;
                case &apos;m&apos;:
                    cpx += p[off++];
                    cpy += p[off++];
                    cmd = CMD.M;
                    path.addData(cmd, cpx, cpy);
                    c = &apos;l&apos;;
                    break;
                case &apos;M&apos;:
                    cpx = p[off++];
                    cpy = p[off++];
                    cmd = CMD.M;
                    path.addData(cmd, cpx, cpy);
                    c = &apos;L&apos;;
                    break;
                case &apos;h&apos;:
                    cpx += p[off++];
                    cmd = CMD.L;
                    path.addData(cmd, cpx, cpy);
                    break;
                case &apos;H&apos;:
                    cpx = p[off++];
                    cmd = CMD.L;
                    path.addData(cmd, cpx, cpy);
                    break;
                case &apos;v&apos;:
                    cpy += p[off++];
                    cmd = CMD.L;
                    path.addData(cmd, cpx, cpy);
                    break;
                case &apos;V&apos;:
                    cpy = p[off++];
                    cmd = CMD.L;
                    path.addData(cmd, cpx, cpy);
                    break;
                case &apos;C&apos;:
                    cmd = CMD.C;
                    path.addData(cmd, p[off++], p[off++], p[off++], p[off++], p[off++], p[off++]);
                    cpx = p[off - 2];
                    cpy = p[off - 1];
                    break;
                case &apos;c&apos;:
                    cmd = CMD.C;
                    path.addData(cmd, p[off++] + cpx, p[off++] + cpy, p[off++] + cpx, p[off++] + cpy, p[off++] + cpx, p[off++] + cpy);
                    cpx += p[off - 2];
                    cpy += p[off - 1];
                    break;
                case &apos;S&apos;:
                    ctlPtx = cpx;
                    ctlPty = cpy;
                    var len = path.len();
                    var pathData = path.data;
                    if (prevCmd === CMD.C) {
                        ctlPtx += cpx - pathData[len - 4];
                        ctlPty += cpy - pathData[len - 3];
                    }
                    cmd = CMD.C;
                    x1 = p[off++];
                    y1 = p[off++];
                    cpx = p[off++];
                    cpy = p[off++];
                    path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);
                    break;
                case &apos;s&apos;:
                    ctlPtx = cpx;
                    ctlPty = cpy;
                    var len = path.len();
                    var pathData = path.data;
                    if (prevCmd === CMD.C) {
                        ctlPtx += cpx - pathData[len - 4];
                        ctlPty += cpy - pathData[len - 3];
                    }
                    cmd = CMD.C;
                    x1 = cpx + p[off++];
                    y1 = cpy + p[off++];
                    cpx += p[off++];
                    cpy += p[off++];
                    path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);
                    break;
                case &apos;Q&apos;:
                    x1 = p[off++];
                    y1 = p[off++];
                    cpx = p[off++];
                    cpy = p[off++];
                    cmd = CMD.Q;
                    path.addData(cmd, x1, y1, cpx, cpy);
                    break;
                case &apos;q&apos;:
                    x1 = p[off++] + cpx;
                    y1 = p[off++] + cpy;
                    cpx += p[off++];
                    cpy += p[off++];
                    cmd = CMD.Q;
                    path.addData(cmd, x1, y1, cpx, cpy);
                    break;
                case &apos;T&apos;:
                    ctlPtx = cpx;
                    ctlPty = cpy;
                    var len = path.len();
                    var pathData = path.data;
                    if (prevCmd === CMD.Q) {
                        ctlPtx += cpx - pathData[len - 4];
                        ctlPty += cpy - pathData[len - 3];
                    }
                    cpx = p[off++];
                    cpy = p[off++];
                    cmd = CMD.Q;
                    path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);
                    break;
                case &apos;t&apos;:
                    ctlPtx = cpx;
                    ctlPty = cpy;
                    var len = path.len();
                    var pathData = path.data;
                    if (prevCmd === CMD.Q) {
                        ctlPtx += cpx - pathData[len - 4];
                        ctlPty += cpy - pathData[len - 3];
                    }
                    cpx += p[off++];
                    cpy += p[off++];
                    cmd = CMD.Q;
                    path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);
                    break;
                case &apos;A&apos;:
                    rx = p[off++];
                    ry = p[off++];
                    psi = p[off++];
                    fa = p[off++];
                    fs = p[off++];
                    x1 = cpx, y1 = cpy;
                    cpx = p[off++];
                    cpy = p[off++];
                    cmd = CMD.A;
                    processArc(x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path);
                    break;
                case &apos;a&apos;:
                    rx = p[off++];
                    ry = p[off++];
                    psi = p[off++];
                    fa = p[off++];
                    fs = p[off++];
                    x1 = cpx, y1 = cpy;
                    cpx += p[off++];
                    cpy += p[off++];
                    cmd = CMD.A;
                    processArc(x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path);
                    break;
                }
            }
            if (c === &apos;z&apos; || c === &apos;Z&apos;) {
                cmd = CMD.Z;
                path.addData(cmd);
            }
            prevCmd = cmd;
        }
        path.toStatic();
        return path;
    }
    // TODO Optimize double memory cost problem
    function createPathOptions(str, opts) {
        var pathProxy = createPathProxyFromString(str);
        var transform;
        opts = opts || {};
        opts.buildPath = function (path) {
            path.setData(pathProxy.data);
            transform &amp;&amp; transformPath(path, transform);
            // Svg and vml renderer don&apos;t have context
            var ctx = path.getContext();
            if (ctx) {
                path.rebuildPath(ctx);
            }
        };
        opts.applyTransform = function (m) {
            if (!transform) {
                transform = matrix.create();
            }
            matrix.mul(transform, m, transform);
        };
        return opts;
    }
    return {
        createFromString: function (str, opts) {
            return new Path(createPathOptions(str, opts));
        },
        extendFromString: function (str, opts) {
            return Path.extend(createPathOptions(str, opts));
        },
        mergePath: function (pathEls, opts) {
            var pathList = [];
            var len = pathEls.length;
            for (var i = 0; i &lt; len; i++) {
                var pathEl = pathEls[i];
                if (pathEl.__dirty) {
                    pathEl.buildPath(pathEl.path, pathEl.shape, true);
                }
                pathList.push(pathEl.path);
            }
            var pathBundle = new Path(opts);
            pathBundle.buildPath = function (path) {
                path.appendPath(pathList);
                // Svg and vml renderer don&apos;t have context
                var ctx = path.getContext();
                if (ctx) {
                    path.rebuildPath(ctx);
                }
            };
            return pathBundle;
        }
    };
});
define(&apos;zrender/graphic/Text&apos;, [&apos;require&apos;, &apos;./Displayable&apos;, &apos;../core/util&apos;, &apos;../contain/text&apos;], function (require) {
    var Displayable = require(&apos;./Displayable&apos;);
    var zrUtil = require(&apos;../core/util&apos;);
    var textContain = require(&apos;../contain/text&apos;);
    /**
     * @alias zrender/graphic/Text
     * @extends module:zrender/graphic/Displayable
     * @constructor
     * @param {Object} opts
     */
    var Text = function (opts) {
        Displayable.call(this, opts);
    };
    Text.prototype = {
        constructor: Text,
        type: &apos;text&apos;,
        brush: function (ctx, prevEl) {
            var style = this.style;
            var x = style.x || 0;
            var y = style.y || 0;
            // Convert to string
            var text = style.text;
            // Convert to string
            text != null &amp;&amp; (text += &apos;&apos;);
            // Always bind style
            style.bind(ctx, this, prevEl);
            if (text) {
                this.setTransform(ctx);
                var textBaseline;
                var textAlign = style.textAlign;
                var font = style.textFont || style.font;
                if (style.textVerticalAlign) {
                    var rect = textContain.getBoundingRect(text, font, style.textAlign, &apos;top&apos;);
                    // Ignore textBaseline
                    textBaseline = &apos;middle&apos;;
                    switch (style.textVerticalAlign) {
                    case &apos;middle&apos;:
                        y -= rect.height / 2 - rect.lineHeight / 2;
                        break;
                    case &apos;bottom&apos;:
                        y -= rect.height - rect.lineHeight / 2;
                        break;
                    default:
                        y += rect.lineHeight / 2;
                    }
                } else {
                    textBaseline = style.textBaseline;
                }
                ctx.font = font;
                ctx.textAlign = textAlign || &apos;left&apos;;
                // Use canvas default left textAlign. Giving invalid value will cause state not change
                if (ctx.textAlign !== textAlign) {
                    ctx.textAlign = &apos;left&apos;;
                }
                ctx.textBaseline = textBaseline || &apos;alphabetic&apos;;
                // Use canvas default alphabetic baseline
                if (ctx.textBaseline !== textBaseline) {
                    ctx.textBaseline = &apos;alphabetic&apos;;
                }
                var lineHeight = textContain.measureText(&apos;&#x56FD;&apos;, ctx.font).width;
                var textLines = text.split(&apos;\n&apos;);
                for (var i = 0; i &lt; textLines.length; i++) {
                    style.hasFill() &amp;&amp; ctx.fillText(textLines[i], x, y);
                    style.hasStroke() &amp;&amp; ctx.strokeText(textLines[i], x, y);
                    y += lineHeight;
                }
                this.restoreTransform(ctx);
            }
        },
        getBoundingRect: function () {
            if (!this._rect) {
                var style = this.style;
                var textVerticalAlign = style.textVerticalAlign;
                var rect = textContain.getBoundingRect(style.text + &apos;&apos;, style.textFont || style.font, style.textAlign, textVerticalAlign ? &apos;top&apos; : style.textBaseline);
                switch (textVerticalAlign) {
                case &apos;middle&apos;:
                    rect.y -= rect.height / 2;
                    break;
                case &apos;bottom&apos;:
                    rect.y -= rect.height;
                    break;
                }
                rect.x += style.x || 0;
                rect.y += style.y || 0;
                this._rect = rect;
            }
            return this._rect;
        }
    };
    zrUtil.inherits(Text, Displayable);
    return Text;
});
define(&apos;zrender/graphic/Image&apos;, [&apos;require&apos;, &apos;./Displayable&apos;, &apos;../core/BoundingRect&apos;, &apos;../core/util&apos;, &apos;../core/LRU&apos;], function (require) {
    var Displayable = require(&apos;./Displayable&apos;);
    var BoundingRect = require(&apos;../core/BoundingRect&apos;);
    var zrUtil = require(&apos;../core/util&apos;);
    var LRU = require(&apos;../core/LRU&apos;);
    var globalImageCache = new LRU(50);
    /**
     * @alias zrender/graphic/Image
     * @extends module:zrender/graphic/Displayable
     * @constructor
     * @param {Object} opts
     */
    function ZImage(opts) {
        Displayable.call(this, opts);
    }
    ZImage.prototype = {
        constructor: ZImage,
        type: &apos;image&apos;,
        brush: function (ctx, prevEl) {
            var style = this.style;
            var src = style.image;
            var image;
            // Must bind each time
            style.bind(ctx, this, prevEl);
            // style.image is a url string
            if (typeof src === &apos;string&apos;) {
                image = this._image;
            }    // style.image is an HTMLImageElement or HTMLCanvasElement or Canvas
            else {
                image = src;
            }
            // FIXME Case create many images with src
            if (!image &amp;&amp; src) {
                // Try get from global image cache
                var cachedImgObj = globalImageCache.get(src);
                if (!cachedImgObj) {
                    // Create a new image
                    image = new Image();
                    image.onload = function () {
                        image.onload = null;
                        for (var i = 0; i &lt; cachedImgObj.pending.length; i++) {
                            cachedImgObj.pending[i].dirty();
                        }
                    };
                    cachedImgObj = {
                        image: image,
                        pending: [this]
                    };
                    image.src = src;
                    globalImageCache.put(src, cachedImgObj);
                    this._image = image;
                    return;
                } else {
                    image = cachedImgObj.image;
                    this._image = image;
                    // Image is not complete finish, add to pending list
                    if (!image.width || !image.height) {
                        cachedImgObj.pending.push(this);
                        return;
                    }
                }
            }
            if (image) {
                // &#x56FE;&#x7247;&#x5DF2;&#x7ECF;&#x52A0;&#x8F7D;&#x5B8C;&#x6210;
                // if (image.nodeName.toUpperCase() == &apos;IMG&apos;) {
                //     if (!image.complete) {
                //         return;
                //     }
                // }
                // Else is canvas
                var width = style.width || image.width;
                var height = style.height || image.height;
                var x = style.x || 0;
                var y = style.y || 0;
                // &#x56FE;&#x7247;&#x52A0;&#x8F7D;&#x5931;&#x8D25;
                if (!image.width || !image.height) {
                    return;
                }
                // &#x8BBE;&#x7F6E;transform
                this.setTransform(ctx);
                if (style.sWidth &amp;&amp; style.sHeight) {
                    var sx = style.sx || 0;
                    var sy = style.sy || 0;
                    ctx.drawImage(image, sx, sy, style.sWidth, style.sHeight, x, y, width, height);
                } else if (style.sx &amp;&amp; style.sy) {
                    var sx = style.sx;
                    var sy = style.sy;
                    var sWidth = width - sx;
                    var sHeight = height - sy;
                    ctx.drawImage(image, sx, sy, sWidth, sHeight, x, y, width, height);
                } else {
                    ctx.drawImage(image, x, y, width, height);
                }
                // &#x5982;&#x679C;&#x6CA1;&#x8BBE;&#x7F6E;&#x5BBD;&#x548C;&#x9AD8;&#x7684;&#x8BDD;&#x81EA;&#x52A8;&#x6839;&#x636E;&#x56FE;&#x7247;&#x5BBD;&#x9AD8;&#x8BBE;&#x7F6E;
                if (style.width == null) {
                    style.width = width;
                }
                if (style.height == null) {
                    style.height = height;
                }
                this.restoreTransform(ctx);
                // Draw rect text
                if (style.text != null) {
                    this.drawRectText(ctx, this.getBoundingRect());
                }
            }
        },
        getBoundingRect: function () {
            var style = this.style;
            if (!this._rect) {
                this._rect = new BoundingRect(style.x || 0, style.y || 0, style.width || 0, style.height || 0);
            }
            return this._rect;
        }
    };
    zrUtil.inherits(ZImage, Displayable);
    return ZImage;
});
define(&apos;zrender/graphic/shape/Sector&apos;, [&apos;require&apos;, &apos;../Path&apos;], function (require) {
    return require(&apos;../Path&apos;).extend({
        type: &apos;sector&apos;,
        shape: {
            cx: 0,
            cy: 0,
            r0: 0,
            r: 0,
            startAngle: 0,
            endAngle: Math.PI * 2,
            clockwise: true
        },
        buildPath: function (ctx, shape) {
            var x = shape.cx;
            var y = shape.cy;
            var r0 = Math.max(shape.r0 || 0, 0);
            var r = Math.max(shape.r, 0);
            var startAngle = shape.startAngle;
            var endAngle = shape.endAngle;
            var clockwise = shape.clockwise;
            var unitX = Math.cos(startAngle);
            var unitY = Math.sin(startAngle);
            ctx.moveTo(unitX * r0 + x, unitY * r0 + y);
            ctx.lineTo(unitX * r + x, unitY * r + y);
            ctx.arc(x, y, r, startAngle, endAngle, !clockwise);
            ctx.lineTo(Math.cos(endAngle) * r0 + x, Math.sin(endAngle) * r0 + y);
            if (r0 !== 0) {
                ctx.arc(x, y, r0, endAngle, startAngle, clockwise);
            }
            ctx.closePath();
        }
    });
});
define(&apos;zrender/graphic/shape/Polyline&apos;, [&apos;require&apos;, &apos;../helper/poly&apos;, &apos;../Path&apos;], function (require) {
    var polyHelper = require(&apos;../helper/poly&apos;);
    return require(&apos;../Path&apos;).extend({
        type: &apos;polyline&apos;,
        shape: {
            points: null,
            smooth: false,
            smoothConstraint: null
        },
        style: {
            stroke: &apos;#000&apos;,
            fill: null
        },
        buildPath: function (ctx, shape) {
            polyHelper.buildPath(ctx, shape, false);
        }
    });
});
define(&apos;zrender/graphic/shape/Rect&apos;, [&apos;require&apos;, &apos;../helper/roundRect&apos;, &apos;../Path&apos;], function (require) {
    var roundRectHelper = require(&apos;../helper/roundRect&apos;);
    return require(&apos;../Path&apos;).extend({
        type: &apos;rect&apos;,
        shape: {
            r: 0,
            x: 0,
            y: 0,
            width: 0,
            height: 0
        },
        buildPath: function (ctx, shape) {
            var x = shape.x;
            var y = shape.y;
            var width = shape.width;
            var height = shape.height;
            if (!shape.r) {
                ctx.rect(x, y, width, height);
            } else {
                roundRectHelper.buildPath(ctx, shape);
            }
            ctx.closePath();
            return;
        }
    });
});
define(&apos;zrender/graphic/shape/Line&apos;, [&apos;require&apos;, &apos;../Path&apos;], function (require) {
    return require(&apos;../Path&apos;).extend({
        type: &apos;line&apos;,
        shape: {
            x1: 0,
            y1: 0,
            x2: 0,
            y2: 0,
            percent: 1
        },
        style: {
            stroke: &apos;#000&apos;,
            fill: null
        },
        buildPath: function (ctx, shape) {
            var x1 = shape.x1;
            var y1 = shape.y1;
            var x2 = shape.x2;
            var y2 = shape.y2;
            var percent = shape.percent;
            if (percent === 0) {
                return;
            }
            ctx.moveTo(x1, y1);
            if (percent &lt; 1) {
                x2 = x1 * (1 - percent) + x2 * percent;
                y2 = y1 * (1 - percent) + y2 * percent;
            }
            ctx.lineTo(x2, y2);
        },
        pointAt: function (p) {
            var shape = this.shape;
            return [
                shape.x1 * (1 - p) + shape.x2 * p,
                shape.y1 * (1 - p) + shape.y2 * p
            ];
        }
    });
});
define(&apos;zrender/graphic/shape/Ring&apos;, [&apos;require&apos;, &apos;../Path&apos;], function (require) {
    return require(&apos;../Path&apos;).extend({
        type: &apos;ring&apos;,
        shape: {
            cx: 0,
            cy: 0,
            r: 0,
            r0: 0
        },
        buildPath: function (ctx, shape) {
            var x = shape.cx;
            var y = shape.cy;
            var PI2 = Math.PI * 2;
            ctx.moveTo(x + shape.r, y);
            ctx.arc(x, y, shape.r, 0, PI2, false);
            ctx.moveTo(x + shape.r0, y);
            ctx.arc(x, y, shape.r0, 0, PI2, true);
        }
    });
});
define(&apos;zrender/graphic/shape/Polygon&apos;, [&apos;require&apos;, &apos;../helper/poly&apos;, &apos;../Path&apos;], function (require) {
    var polyHelper = require(&apos;../helper/poly&apos;);
    return require(&apos;../Path&apos;).extend({
        type: &apos;polygon&apos;,
        shape: {
            points: null,
            smooth: false,
            smoothConstraint: null
        },
        buildPath: function (ctx, shape) {
            polyHelper.buildPath(ctx, shape, true);
        }
    });
});
define(&apos;zrender/graphic/shape/BezierCurve&apos;, [&apos;require&apos;, &apos;../../core/curve&apos;, &apos;../../core/vector&apos;, &apos;../Path&apos;], function (require) {
    &apos;use strict&apos;;
    var curveTool = require(&apos;../../core/curve&apos;);
    var vec2 = require(&apos;../../core/vector&apos;);
    var quadraticSubdivide = curveTool.quadraticSubdivide;
    var cubicSubdivide = curveTool.cubicSubdivide;
    var quadraticAt = curveTool.quadraticAt;
    var cubicAt = curveTool.cubicAt;
    var quadraticDerivativeAt = curveTool.quadraticDerivativeAt;
    var cubicDerivativeAt = curveTool.cubicDerivativeAt;
    var out = [];
    function someVectorAt(shape, t, isTangent) {
        var cpx2 = shape.cpx2;
        var cpy2 = shape.cpy2;
        if (cpx2 === null || cpy2 === null) {
            return [
                (isTangent ? cubicDerivativeAt : cubicAt)(shape.x1, shape.cpx1, shape.cpx2, shape.x2, t),
                (isTangent ? cubicDerivativeAt : cubicAt)(shape.y1, shape.cpy1, shape.cpy2, shape.y2, t)
            ];
        } else {
            return [
                (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.x1, shape.cpx1, shape.x2, t),
                (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.y1, shape.cpy1, shape.y2, t)
            ];
        }
    }
    return require(&apos;../Path&apos;).extend({
        type: &apos;bezier-curve&apos;,
        shape: {
            x1: 0,
            y1: 0,
            x2: 0,
            y2: 0,
            cpx1: 0,
            cpy1: 0,
            percent: 1
        },
        style: {
            stroke: &apos;#000&apos;,
            fill: null
        },
        buildPath: function (ctx, shape) {
            var x1 = shape.x1;
            var y1 = shape.y1;
            var x2 = shape.x2;
            var y2 = shape.y2;
            var cpx1 = shape.cpx1;
            var cpy1 = shape.cpy1;
            var cpx2 = shape.cpx2;
            var cpy2 = shape.cpy2;
            var percent = shape.percent;
            if (percent === 0) {
                return;
            }
            ctx.moveTo(x1, y1);
            if (cpx2 == null || cpy2 == null) {
                if (percent &lt; 1) {
                    quadraticSubdivide(x1, cpx1, x2, percent, out);
                    cpx1 = out[1];
                    x2 = out[2];
                    quadraticSubdivide(y1, cpy1, y2, percent, out);
                    cpy1 = out[1];
                    y2 = out[2];
                }
                ctx.quadraticCurveTo(cpx1, cpy1, x2, y2);
            } else {
                if (percent &lt; 1) {
                    cubicSubdivide(x1, cpx1, cpx2, x2, percent, out);
                    cpx1 = out[1];
                    cpx2 = out[2];
                    x2 = out[3];
                    cubicSubdivide(y1, cpy1, cpy2, y2, percent, out);
                    cpy1 = out[1];
                    cpy2 = out[2];
                    y2 = out[3];
                }
                ctx.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x2, y2);
            }
        },
        pointAt: function (t) {
            return someVectorAt(this.shape, t, false);
        },
        tangentAt: function (t) {
            var p = someVectorAt(this.shape, t, true);
            return vec2.normalize(p, p);
        }
    });
});
define(&apos;zrender/graphic/shape/Arc&apos;, [&apos;require&apos;, &apos;../Path&apos;], function (require) {
    return require(&apos;../Path&apos;).extend({
        type: &apos;arc&apos;,
        shape: {
            cx: 0,
            cy: 0,
            r: 0,
            startAngle: 0,
            endAngle: Math.PI * 2,
            clockwise: true
        },
        style: {
            stroke: &apos;#000&apos;,
            fill: null
        },
        buildPath: function (ctx, shape) {
            var x = shape.cx;
            var y = shape.cy;
            var r = Math.max(shape.r, 0);
            var startAngle = shape.startAngle;
            var endAngle = shape.endAngle;
            var clockwise = shape.clockwise;
            var unitX = Math.cos(startAngle);
            var unitY = Math.sin(startAngle);
            ctx.moveTo(unitX * r + x, unitY * r + y);
            ctx.arc(x, y, r, startAngle, endAngle, !clockwise);
        }
    });
});
define(&apos;zrender/graphic/LinearGradient&apos;, [&apos;require&apos;, &apos;../core/util&apos;, &apos;./Gradient&apos;], function (require) {
    &apos;use strict&apos;;
    var zrUtil = require(&apos;../core/util&apos;);
    var Gradient = require(&apos;./Gradient&apos;);
    /**
     * x, y, x2, y2 are all percent from 0 to 1
     * @param {number} [x=0]
     * @param {number} [y=0]
     * @param {number} [x2=1]
     * @param {number} [y2=0]
     * @param {Array.<object>} colorStops
     * @param {boolean} [globalCoord=false]
     */
    var LinearGradient = function (x, y, x2, y2, colorStops, globalCoord) {
        this.x = x == null ? 0 : x;
        this.y = y == null ? 0 : y;
        this.x2 = x2 == null ? 1 : x2;
        this.y2 = y2 == null ? 0 : y2;
        // Can be cloned
        this.type = &apos;linear&apos;;
        // If use global coord
        this.global = globalCoord || false;
        Gradient.call(this, colorStops);
    };
    LinearGradient.prototype = { constructor: LinearGradient };
    zrUtil.inherits(LinearGradient, Gradient);
    return LinearGradient;
});
define(&apos;zrender/graphic/CompoundPath&apos;, [&apos;require&apos;, &apos;./Path&apos;], function (require) {
    var Path = require(&apos;./Path&apos;);
    return Path.extend({
        type: &apos;compound&apos;,
        shape: { paths: null },
        _updatePathDirty: function () {
            var dirtyPath = this.__dirtyPath;
            var paths = this.shape.paths;
            for (var i = 0; i &lt; paths.length; i++) {
                // Mark as dirty if any subpath is dirty
                dirtyPath = dirtyPath || paths[i].__dirtyPath;
            }
            this.__dirtyPath = dirtyPath;
            this.__dirty = this.__dirty || dirtyPath;
        },
        beforeBrush: function () {
            this._updatePathDirty();
            var paths = this.shape.paths || [];
            var scale = this.getGlobalScale();
            // Update path scale
            for (var i = 0; i &lt; paths.length; i++) {
                paths[i].path.setScale(scale[0], scale[1]);
            }
        },
        buildPath: function (ctx, shape) {
            var paths = shape.paths || [];
            for (var i = 0; i &lt; paths.length; i++) {
                paths[i].buildPath(ctx, paths[i].shape, true);
            }
        },
        afterBrush: function () {
            var paths = this.shape.paths;
            for (var i = 0; i &lt; paths.length; i++) {
                paths[i].__dirtyPath = false;
            }
        },
        getBoundingRect: function () {
            this._updatePathDirty();
            return Path.prototype.getBoundingRect.call(this);
        }
    });
});
define(&apos;zrender/graphic/RadialGradient&apos;, [&apos;require&apos;, &apos;../core/util&apos;, &apos;./Gradient&apos;], function (require) {
    &apos;use strict&apos;;
    var zrUtil = require(&apos;../core/util&apos;);
    var Gradient = require(&apos;./Gradient&apos;);
    /**
     * x, y, r are all percent from 0 to 1
     * @param {number} [x=0.5]
     * @param {number} [y=0.5]
     * @param {number} [r=0.5]
     * @param {Array.<object>} [colorStops]
     * @param {boolean} [globalCoord=false]
     */
    var RadialGradient = function (x, y, r, colorStops, globalCoord) {
        this.x = x == null ? 0.5 : x;
        this.y = y == null ? 0.5 : y;
        this.r = r == null ? 0.5 : r;
        // Can be cloned
        this.type = &apos;radial&apos;;
        // If use global coord
        this.global = globalCoord || false;
        Gradient.call(this, colorStops);
    };
    RadialGradient.prototype = { constructor: RadialGradient };
    zrUtil.inherits(RadialGradient, Gradient);
    return RadialGradient;
});
define(&apos;zrender/core/PathProxy&apos;, [&apos;require&apos;, &apos;./curve&apos;, &apos;./vector&apos;, &apos;./bbox&apos;, &apos;./BoundingRect&apos;, &apos;../config&apos;], function (require) {
    &apos;use strict&apos;;
    var curve = require(&apos;./curve&apos;);
    var vec2 = require(&apos;./vector&apos;);
    var bbox = require(&apos;./bbox&apos;);
    var BoundingRect = require(&apos;./BoundingRect&apos;);
    var dpr = require(&apos;../config&apos;).devicePixelRatio;
    var CMD = {
            M: 1,
            L: 2,
            C: 3,
            Q: 4,
            A: 5,
            Z: 6,
            R: 7
        };
    var min = [];
    var max = [];
    var min2 = [];
    var max2 = [];
    var mathMin = Math.min;
    var mathMax = Math.max;
    var mathCos = Math.cos;
    var mathSin = Math.sin;
    var mathSqrt = Math.sqrt;
    var mathAbs = Math.abs;
    var hasTypedArray = typeof Float32Array != &apos;undefined&apos;;
    /**
     * @alias module:zrender/core/PathProxy
     * @constructor
     */
    var PathProxy = function () {
        /**
         * Path data. Stored as flat array
         * @type {Array.<object>}
         */
        this.data = [];
        this._len = 0;
        this._ctx = null;
        this._xi = 0;
        this._yi = 0;
        this._x0 = 0;
        this._y0 = 0;
        // Unit x, Unit y. Provide for avoiding drawing that too short line segment
        this._ux = 0;
        this._uy = 0;
    };
    /**
     * &#x5FEB;&#x901F;&#x8BA1;&#x7B97;Path&#x5305;&#x56F4;&#x76D2;&#xFF08;&#x5E76;&#x4E0D;&#x662F;&#x6700;&#x5C0F;&#x5305;&#x56F4;&#x76D2;&#xFF09;
     * @return {Object}
     */
    PathProxy.prototype = {
        constructor: PathProxy,
        _lineDash: null,
        _dashOffset: 0,
        _dashIdx: 0,
        _dashSum: 0,
        setScale: function (sx, sy) {
            this._ux = mathAbs(1 / dpr / sx) || 0;
            this._uy = mathAbs(1 / dpr / sy) || 0;
        },
        getContext: function () {
            return this._ctx;
        },
        beginPath: function (ctx) {
            this._ctx = ctx;
            ctx &amp;&amp; ctx.beginPath();
            // Reset
            this._len = 0;
            if (this._lineDash) {
                this._lineDash = null;
                this._dashOffset = 0;
            }
            return this;
        },
        moveTo: function (x, y) {
            this.addData(CMD.M, x, y);
            this._ctx &amp;&amp; this._ctx.moveTo(x, y);
            // x0, y0, xi, yi &#x662F;&#x8BB0;&#x5F55;&#x5728; _dashedXXXXTo &#x65B9;&#x6CD5;&#x4E2D;&#x4F7F;&#x7528;
            // xi, yi &#x8BB0;&#x5F55;&#x5F53;&#x524D;&#x70B9;, x0, y0 &#x5728; closePath &#x7684;&#x65F6;&#x5019;&#x56DE;&#x5230;&#x8D77;&#x59CB;&#x70B9;&#x3002;
            // &#x6709;&#x53EF;&#x80FD;&#x5728; beginPath &#x4E4B;&#x540E;&#x76F4;&#x63A5;&#x8C03;&#x7528; lineTo&#xFF0C;&#x8FD9;&#x65F6;&#x5019; x0, y0 &#x9700;&#x8981;
            // &#x5728; lineTo &#x65B9;&#x6CD5;&#x4E2D;&#x8BB0;&#x5F55;&#xFF0C;&#x8FD9;&#x91CC;&#x5148;&#x4E0D;&#x8003;&#x8651;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#xFF0C;dashed line &#x4E5F;&#x53EA;&#x5728; IE10- &#x4E2D;&#x4E0D;&#x652F;&#x6301;
            this._x0 = x;
            this._y0 = y;
            this._xi = x;
            this._yi = y;
            return this;
        },
        lineTo: function (x, y) {
            var exceedUnit = mathAbs(x - this._xi) &gt; this._ux || mathAbs(y - this._yi) &gt; this._uy || this._len &lt; 5;
            this.addData(CMD.L, x, y);
            if (this._ctx &amp;&amp; exceedUnit) {
                this._needsDash() ? this._dashedLineTo(x, y) : this._ctx.lineTo(x, y);
            }
            if (exceedUnit) {
                this._xi = x;
                this._yi = y;
            }
            return this;
        },
        bezierCurveTo: function (x1, y1, x2, y2, x3, y3) {
            this.addData(CMD.C, x1, y1, x2, y2, x3, y3);
            if (this._ctx) {
                this._needsDash() ? this._dashedBezierTo(x1, y1, x2, y2, x3, y3) : this._ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
            }
            this._xi = x3;
            this._yi = y3;
            return this;
        },
        quadraticCurveTo: function (x1, y1, x2, y2) {
            this.addData(CMD.Q, x1, y1, x2, y2);
            if (this._ctx) {
                this._needsDash() ? this._dashedQuadraticTo(x1, y1, x2, y2) : this._ctx.quadraticCurveTo(x1, y1, x2, y2);
            }
            this._xi = x2;
            this._yi = y2;
            return this;
        },
        arc: function (cx, cy, r, startAngle, endAngle, anticlockwise) {
            this.addData(CMD.A, cx, cy, r, r, startAngle, endAngle - startAngle, 0, anticlockwise ? 0 : 1);
            this._ctx &amp;&amp; this._ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise);
            this._xi = mathCos(endAngle) * r + cx;
            this._xi = mathSin(endAngle) * r + cx;
            return this;
        },
        arcTo: function (x1, y1, x2, y2, radius) {
            if (this._ctx) {
                this._ctx.arcTo(x1, y1, x2, y2, radius);
            }
            return this;
        },
        rect: function (x, y, w, h) {
            this._ctx &amp;&amp; this._ctx.rect(x, y, w, h);
            this.addData(CMD.R, x, y, w, h);
            return this;
        },
        closePath: function () {
            this.addData(CMD.Z);
            var ctx = this._ctx;
            var x0 = this._x0;
            var y0 = this._y0;
            if (ctx) {
                this._needsDash() &amp;&amp; this._dashedLineTo(x0, y0);
                ctx.closePath();
            }
            this._xi = x0;
            this._yi = y0;
            return this;
        },
        fill: function (ctx) {
            ctx &amp;&amp; ctx.fill();
            this.toStatic();
        },
        stroke: function (ctx) {
            ctx &amp;&amp; ctx.stroke();
            this.toStatic();
        },
        setLineDash: function (lineDash) {
            if (lineDash instanceof Array) {
                this._lineDash = lineDash;
                this._dashIdx = 0;
                var lineDashSum = 0;
                for (var i = 0; i &lt; lineDash.length; i++) {
                    lineDashSum += lineDash[i];
                }
                this._dashSum = lineDashSum;
            }
            return this;
        },
        setLineDashOffset: function (offset) {
            this._dashOffset = offset;
            return this;
        },
        len: function () {
            return this._len;
        },
        setData: function (data) {
            var len = data.length;
            if (!(this.data &amp;&amp; this.data.length == len) &amp;&amp; hasTypedArray) {
                this.data = new Float32Array(len);
            }
            for (var i = 0; i &lt; len; i++) {
                this.data[i] = data[i];
            }
            this._len = len;
        },
        appendPath: function (path) {
            if (!(path instanceof Array)) {
                path = [path];
            }
            var len = path.length;
            var appendSize = 0;
            var offset = this._len;
            for (var i = 0; i &lt; len; i++) {
                appendSize += path[i].len();
            }
            if (hasTypedArray &amp;&amp; this.data instanceof Float32Array) {
                this.data = new Float32Array(offset + appendSize);
            }
            for (var i = 0; i &lt; len; i++) {
                var appendPathData = path[i].data;
                for (var k = 0; k &lt; appendPathData.length; k++) {
                    this.data[offset++] = appendPathData[k];
                }
            }
            this._len = offset;
        },
        addData: function (cmd) {
            var data = this.data;
            if (this._len + arguments.length &gt; data.length) {
                // &#x56E0;&#x4E3A;&#x4E4B;&#x524D;&#x7684;&#x6570;&#x7EC4;&#x5DF2;&#x7ECF;&#x8F6C;&#x6362;&#x6210;&#x9759;&#x6001;&#x7684; Float32Array
                // &#x6240;&#x4EE5;&#x4E0D;&#x591F;&#x7528;&#x65F6;&#x9700;&#x8981;&#x6269;&#x5C55;&#x4E00;&#x4E2A;&#x65B0;&#x7684;&#x52A8;&#x6001;&#x6570;&#x7EC4;
                this._expandData();
                data = this.data;
            }
            for (var i = 0; i &lt; arguments.length; i++) {
                data[this._len++] = arguments[i];
            }
            this._prevCmd = cmd;
        },
        _expandData: function () {
            // Only if data is Float32Array
            if (!(this.data instanceof Array)) {
                var newData = [];
                for (var i = 0; i &lt; this._len; i++) {
                    newData[i] = this.data[i];
                }
                this.data = newData;
            }
        },
        _needsDash: function () {
            return this._lineDash;
        },
        _dashedLineTo: function (x1, y1) {
            var dashSum = this._dashSum;
            var offset = this._dashOffset;
            var lineDash = this._lineDash;
            var ctx = this._ctx;
            var x0 = this._xi;
            var y0 = this._yi;
            var dx = x1 - x0;
            var dy = y1 - y0;
            var dist = mathSqrt(dx * dx + dy * dy);
            var x = x0;
            var y = y0;
            var dash;
            var nDash = lineDash.length;
            var idx;
            dx /= dist;
            dy /= dist;
            if (offset &lt; 0) {
                // Convert to positive offset
                offset = dashSum + offset;
            }
            offset %= dashSum;
            x -= offset * dx;
            y -= offset * dy;
            while (dx &gt; 0 &amp;&amp; x <= 0="" x1="" ||="" dx="" <="" &&="" x="">= x1 || dx == 0 &amp;&amp; (dy &gt; 0 &amp;&amp; y <= 0="" y1="" ||="" dy="" <="" &&="" y="">= y1)) {
                idx = this._dashIdx;
                dash = lineDash[idx];
                x += dx * dash;
                y += dy * dash;
                this._dashIdx = (idx + 1) % nDash;
                // Skip positive offset
                if (dx &gt; 0 &amp;&amp; x &lt; x0 || dx &lt; 0 &amp;&amp; x &gt; x0 || dy &gt; 0 &amp;&amp; y &lt; y0 || dy &lt; 0 &amp;&amp; y &gt; y0) {
                    continue;
                }
                ctx[idx % 2 ? &apos;moveTo&apos; : &apos;lineTo&apos;](dx &gt;= 0 ? mathMin(x, x1) : mathMax(x, x1), dy &gt;= 0 ? mathMin(y, y1) : mathMax(y, y1));
            }
            // Offset for next lineTo
            dx = x - x1;
            dy = y - y1;
            this._dashOffset = -mathSqrt(dx * dx + dy * dy);
        },
        _dashedBezierTo: function (x1, y1, x2, y2, x3, y3) {
            var dashSum = this._dashSum;
            var offset = this._dashOffset;
            var lineDash = this._lineDash;
            var ctx = this._ctx;
            var x0 = this._xi;
            var y0 = this._yi;
            var t;
            var dx;
            var dy;
            var cubicAt = curve.cubicAt;
            var bezierLen = 0;
            var idx = this._dashIdx;
            var nDash = lineDash.length;
            var x;
            var y;
            var tmpLen = 0;
            if (offset &lt; 0) {
                // Convert to positive offset
                offset = dashSum + offset;
            }
            offset %= dashSum;
            // Bezier approx length
            for (t = 0; t &lt; 1; t += 0.1) {
                dx = cubicAt(x0, x1, x2, x3, t + 0.1) - cubicAt(x0, x1, x2, x3, t);
                dy = cubicAt(y0, y1, y2, y3, t + 0.1) - cubicAt(y0, y1, y2, y3, t);
                bezierLen += mathSqrt(dx * dx + dy * dy);
            }
            // Find idx after add offset
            for (; idx &lt; nDash; idx++) {
                tmpLen += lineDash[idx];
                if (tmpLen &gt; offset) {
                    break;
                }
            }
            t = (tmpLen - offset) / bezierLen;
            while (t <= 0="" 2="" 1)="" {="" x="cubicAt(x0," x1,="" x2,="" x3,="" t);="" y="cubicAt(y0," y1,="" y2,="" y3,="" use="" line="" to="" approximate="" dashed="" bezier="" bad="" result="" if="" dash="" is="" long="" idx="" %="" ?="" ctx.moveto(x,="" y)="" :="" ctx.lineto(x,="" y);="" t="" +="lineDash[idx]" bezierlen;="" ndash;="" }="" finish="" the="" last="" segment="" and="" calculate="" new="" offset="" !="=" &&="" ctx.lineto(x3,="" y3);="" dx="x3" -="" x;="" dy="y3" y;="" this._dashoffset="-mathSqrt(dx" *="" dy);="" },="" _dashedquadraticto:="" function="" (x1,="" y2)="" convert="" quadratic="" cubic="" using="" degree="" elevation="" var="" x3="x2;" y3="y2;" x2="(x2" x1)="" 3;="" y2="(y2" y1)="" x1="(this._xi" y1="(this._yi" this._dashedbezierto(x1,="" tostatic:="" ()="" data="this.data;" (data="" instanceof="" array)="" data.length="this._len;" (hastypedarray)="" this.data="new" float32array(data);="" getboundingrect:="" min[0]="min[1]" =="" min2[0]="min2[1]" number.max_value;="" max[0]="max[1]" max2[0]="max2[1]" -number.max_value;="" xi="0;" yi="0;" x0="0;" y0="0;" for="" (var="" i="0;" <="" data.length;)="" cmd="data[i++];" (i="=" 如果第一个命令是="" l,="" c,="" q="" 则="" previous="" point="" 同绘制命令的第一个="" 第一个命令为="" arc="" 的情况下会在后面特殊处理="" 1];="" switch="" (cmd)="" case="" cmd.m:="" moveto="" 命令重新创建一个新的="" subpath,="" 并且更新新的起点="" 在="" closepath="" 的时候使用="" min2[1]="y0;" max2[1]="y0;" break;="" cmd.l:="" bbox.fromline(xi,="" yi,="" data[i],="" data[i="" 1],="" min2,="" max2);="" cmd.c:="" bbox.fromcubic(xi,="" data[i++],="" cmd.q:="" bbox.fromquadratic(xi,="" cmd.a:="" todo="" 判断的开销比较大="" cx="data[i++];" cy="data[i++];" rx="data[i++];" ry="data[i++];" startangle="data[i++];" endangle="data[i++]" startangle;="" 旋转="" psi="data[i++];" anticlockwise="1" data[i++];="" 直接使用="" 命令="" 第一个命令起点还未定义="" cx;="" cy;="" bbox.fromarc(cx,="" cy,="" rx,="" ry,="" startangle,="" endangle,="" anticlockwise,="" cmd.r:="" width="data[i++];" height="data[i++];" fromline="" bbox.fromline(x0,="" y0,="" width,="" height,="" cmd.z:="" union="" vec2.min(min,="" min,="" min2);="" vec2.max(max,="" max,="" no="" 0)="" 0;="" return="" boundingrect(min[0],="" min[1],="" min[0],="" max[1]="" min[1]);="" rebuildpath:="" (ctx)="" d="this.data;" x0,="" y0;="" xi,="" yi;="" x,="" ux="this._ux;" uy="this._uy;" len="this._len;" len;)="" d[i++];="" ctx.moveto(xi,="" yi);="" not="" draw="" too="" small="" seg="" between="" (mathabs(x="" xi)=""> ux || mathAbs(y - yi) &gt; uy || i === len - 1) {
                        ctx.lineTo(x, y);
                        xi = x;
                        yi = y;
                    }
                    break;
                case CMD.C:
                    ctx.bezierCurveTo(d[i++], d[i++], d[i++], d[i++], d[i++], d[i++]);
                    xi = d[i - 2];
                    yi = d[i - 1];
                    break;
                case CMD.Q:
                    ctx.quadraticCurveTo(d[i++], d[i++], d[i++], d[i++]);
                    xi = d[i - 2];
                    yi = d[i - 1];
                    break;
                case CMD.A:
                    var cx = d[i++];
                    var cy = d[i++];
                    var rx = d[i++];
                    var ry = d[i++];
                    var theta = d[i++];
                    var dTheta = d[i++];
                    var psi = d[i++];
                    var fs = d[i++];
                    var r = rx &gt; ry ? rx : ry;
                    var scaleX = rx &gt; ry ? 1 : rx / ry;
                    var scaleY = rx &gt; ry ? ry / rx : 1;
                    var isEllipse = Math.abs(rx - ry) &gt; 0.001;
                    var endAngle = theta + dTheta;
                    if (isEllipse) {
                        ctx.translate(cx, cy);
                        ctx.rotate(psi);
                        ctx.scale(scaleX, scaleY);
                        ctx.arc(0, 0, r, theta, endAngle, 1 - fs);
                        ctx.scale(1 / scaleX, 1 / scaleY);
                        ctx.rotate(-psi);
                        ctx.translate(-cx, -cy);
                    } else {
                        ctx.arc(cx, cy, r, theta, endAngle, 1 - fs);
                    }
                    if (i == 1) {
                        // &#x76F4;&#x63A5;&#x4F7F;&#x7528; arc &#x547D;&#x4EE4;
                        // &#x7B2C;&#x4E00;&#x4E2A;&#x547D;&#x4EE4;&#x8D77;&#x70B9;&#x8FD8;&#x672A;&#x5B9A;&#x4E49;
                        x0 = mathCos(theta) * rx + cx;
                        y0 = mathSin(theta) * ry + cy;
                    }
                    xi = mathCos(endAngle) * rx + cx;
                    yi = mathSin(endAngle) * ry + cy;
                    break;
                case CMD.R:
                    x0 = xi = d[i];
                    y0 = yi = d[i + 1];
                    ctx.rect(d[i++], d[i++], d[i++], d[i++]);
                    break;
                case CMD.Z:
                    ctx.closePath();
                    xi = x0;
                    yi = y0;
                }
            }
        }
    };
    PathProxy.CMD = CMD;
    return PathProxy;
});
define(&apos;zrender/tool/transformPath&apos;, [&apos;require&apos;, &apos;../core/PathProxy&apos;, &apos;../core/vector&apos;], function (require) {
    var CMD = require(&apos;../core/PathProxy&apos;).CMD;
    var vec2 = require(&apos;../core/vector&apos;);
    var v2ApplyTransform = vec2.applyTransform;
    var points = [
            [],
            [],
            []
        ];
    var mathSqrt = Math.sqrt;
    var mathAtan2 = Math.atan2;
    function transformPath(path, m) {
        var data = path.data;
        var cmd;
        var nPoint;
        var i;
        var j;
        var k;
        var p;
        var M = CMD.M;
        var C = CMD.C;
        var L = CMD.L;
        var R = CMD.R;
        var A = CMD.A;
        var Q = CMD.Q;
        for (i = 0, j = 0; i &lt; data.length;) {
            cmd = data[i++];
            j = i;
            nPoint = 0;
            switch (cmd) {
            case M:
                nPoint = 1;
                break;
            case L:
                nPoint = 1;
                break;
            case C:
                nPoint = 3;
                break;
            case Q:
                nPoint = 2;
                break;
            case A:
                var x = m[4];
                var y = m[5];
                var sx = mathSqrt(m[0] * m[0] + m[1] * m[1]);
                var sy = mathSqrt(m[2] * m[2] + m[3] * m[3]);
                var angle = mathAtan2(-m[1] / sy, m[0] / sx);
                // cx
                data[i++] += x;
                // cy
                data[i++] += y;
                // Scale rx and ry
                // FIXME Assume psi is 0 here
                data[i++] *= sx;
                data[i++] *= sy;
                // Start angle
                data[i++] += angle;
                // end angle
                data[i++] += angle;
                // FIXME psi
                i += 2;
                j = i;
                break;
            case R:
                // x0, y0
                p[0] = data[i++];
                p[1] = data[i++];
                v2ApplyTransform(p, p, m);
                data[j++] = p[0];
                data[j++] = p[1];
                // x1, y1
                p[0] += data[i++];
                p[1] += data[i++];
                v2ApplyTransform(p, p, m);
                data[j++] = p[0];
                data[j++] = p[1];
            }
            for (k = 0; k &lt; nPoint; k++) {
                var p = points[k];
                p[0] = data[i++];
                p[1] = data[i++];
                v2ApplyTransform(p, p, m);
                // Write back
                data[j++] = p[0];
                data[j++] = p[1];
            }
        }
    }
    return transformPath;
});
define(&apos;zrender/graphic/Displayable&apos;, [&apos;require&apos;, &apos;../core/util&apos;, &apos;./Style&apos;, &apos;../Element&apos;, &apos;./mixin/RectText&apos;], function (require) {
    var zrUtil = require(&apos;../core/util&apos;);
    var Style = require(&apos;./Style&apos;);
    var Element = require(&apos;../Element&apos;);
    var RectText = require(&apos;./mixin/RectText&apos;);
    // var Stateful = require(&apos;./mixin/Stateful&apos;);
    /**
     * @alias module:zrender/graphic/Displayable
     * @extends module:zrender/Element
     * @extends module:zrender/graphic/mixin/RectText
     */
    function Displayable(opts) {
        opts = opts || {};
        Element.call(this, opts);
        // Extend properties
        for (var name in opts) {
            if (opts.hasOwnProperty(name) &amp;&amp; name !== &apos;style&apos;) {
                this[name] = opts[name];
            }
        }
        /**
         * @type {module:zrender/graphic/Style}
         */
        this.style = new Style(opts.style);
        this._rect = null;
        // Shapes for cascade clipping.
        this.__clipPaths = [];    // FIXME Stateful must be mixined after style is setted
                                  // Stateful.call(this, opts);
    }
    Displayable.prototype = {
        constructor: Displayable,
        type: &apos;displayable&apos;,
        __dirty: true,
        invisible: false,
        z: 0,
        z2: 0,
        zlevel: 0,
        draggable: false,
        dragging: false,
        silent: false,
        culling: false,
        cursor: &apos;pointer&apos;,
        rectHover: false,
        progressive: -1,
        beforeBrush: function (ctx) {
        },
        afterBrush: function (ctx) {
        },
        brush: function (ctx, prevEl) {
        },
        getBoundingRect: function () {
        },
        contain: function (x, y) {
            return this.rectContain(x, y);
        },
        traverse: function (cb, context) {
            cb.call(context, this);
        },
        rectContain: function (x, y) {
            var coord = this.transformCoordToLocal(x, y);
            var rect = this.getBoundingRect();
            return rect.contain(coord[0], coord[1]);
        },
        dirty: function () {
            this.__dirty = true;
            this._rect = null;
            this.__zr &amp;&amp; this.__zr.refresh();
        },
        animateStyle: function (loop) {
            return this.animate(&apos;style&apos;, loop);
        },
        attrKV: function (key, value) {
            if (key !== &apos;style&apos;) {
                Element.prototype.attrKV.call(this, key, value);
            } else {
                this.style.set(value);
            }
        },
        setStyle: function (key, value) {
            this.style.set(key, value);
            this.dirty(false);
            return this;
        },
        useStyle: function (obj) {
            this.style = new Style(obj);
            this.dirty(false);
            return this;
        }
    };
    zrUtil.inherits(Displayable, Element);
    zrUtil.mixin(Displayable, RectText);
    // zrUtil.mixin(Displayable, Stateful);
    return Displayable;
});
define(&apos;zrender/contain/path&apos;, [&apos;require&apos;, &apos;../core/PathProxy&apos;, &apos;./line&apos;, &apos;./cubic&apos;, &apos;./quadratic&apos;, &apos;./arc&apos;, &apos;./util&apos;, &apos;../core/curve&apos;, &apos;./windingLine&apos;], function (require) {
    &apos;use strict&apos;;
    var CMD = require(&apos;../core/PathProxy&apos;).CMD;
    var line = require(&apos;./line&apos;);
    var cubic = require(&apos;./cubic&apos;);
    var quadratic = require(&apos;./quadratic&apos;);
    var arc = require(&apos;./arc&apos;);
    var normalizeRadian = require(&apos;./util&apos;).normalizeRadian;
    var curve = require(&apos;../core/curve&apos;);
    var windingLine = require(&apos;./windingLine&apos;);
    var containStroke = line.containStroke;
    var PI2 = Math.PI * 2;
    var EPSILON = 0.0001;
    function isAroundEqual(a, b) {
        return Math.abs(a - b) &lt; EPSILON;
    }
    // &#x4E34;&#x65F6;&#x6570;&#x7EC4;
    var roots = [
            -1,
            -1,
            -1
        ];
    var extrema = [
            -1,
            -1
        ];
    function swapExtrema() {
        var tmp = extrema[0];
        extrema[0] = extrema[1];
        extrema[1] = tmp;
    }
    function windingCubic(x0, y0, x1, y1, x2, y2, x3, y3, x, y) {
        // Quick reject
        if (y &gt; y0 &amp;&amp; y &gt; y1 &amp;&amp; y &gt; y2 &amp;&amp; y &gt; y3 || y &lt; y0 &amp;&amp; y &lt; y1 &amp;&amp; y &lt; y2 &amp;&amp; y &lt; y3) {
            return 0;
        }
        var nRoots = curve.cubicRootAt(y0, y1, y2, y3, y, roots);
        if (nRoots === 0) {
            return 0;
        } else {
            var w = 0;
            var nExtrema = -1;
            var y0_, y1_;
            for (var i = 0; i &lt; nRoots; i++) {
                var t = roots[i];
                // Avoid winding error when intersection point is the connect point of two line of polygon
                var unit = t === 0 || t === 1 ? 0.5 : 1;
                var x_ = curve.cubicAt(x0, x1, x2, x3, t);
                if (x_ &lt; x) {
                    // Quick reject
                    continue;
                }
                if (nExtrema &lt; 0) {
                    nExtrema = curve.cubicExtrema(y0, y1, y2, y3, extrema);
                    if (extrema[1] &lt; extrema[0] &amp;&amp; nExtrema &gt; 1) {
                        swapExtrema();
                    }
                    y0_ = curve.cubicAt(y0, y1, y2, y3, extrema[0]);
                    if (nExtrema &gt; 1) {
                        y1_ = curve.cubicAt(y0, y1, y2, y3, extrema[1]);
                    }
                }
                if (nExtrema == 2) {
                    // &#x5206;&#x6210;&#x4E09;&#x6BB5;&#x5355;&#x8C03;&#x51FD;&#x6570;
                    if (t &lt; extrema[0]) {
                        w += y0_ &lt; y0 ? unit : -unit;
                    } else if (t &lt; extrema[1]) {
                        w += y1_ &lt; y0_ ? unit : -unit;
                    } else {
                        w += y3 &lt; y1_ ? unit : -unit;
                    }
                } else {
                    // &#x5206;&#x6210;&#x4E24;&#x6BB5;&#x5355;&#x8C03;&#x51FD;&#x6570;
                    if (t &lt; extrema[0]) {
                        w += y0_ &lt; y0 ? unit : -unit;
                    } else {
                        w += y3 &lt; y0_ ? unit : -unit;
                    }
                }
            }
            return w;
        }
    }
    function windingQuadratic(x0, y0, x1, y1, x2, y2, x, y) {
        // Quick reject
        if (y &gt; y0 &amp;&amp; y &gt; y1 &amp;&amp; y &gt; y2 || y &lt; y0 &amp;&amp; y &lt; y1 &amp;&amp; y &lt; y2) {
            return 0;
        }
        var nRoots = curve.quadraticRootAt(y0, y1, y2, y, roots);
        if (nRoots === 0) {
            return 0;
        } else {
            var t = curve.quadraticExtremum(y0, y1, y2);
            if (t &gt;= 0 &amp;&amp; t <= 0="" 1="" 1)="" {="" var="" w="0;" y_="curve.quadraticAt(y0," y1,="" y2,="" t);="" for="" (var="" i="0;" <="" nroots;="" i++)="" remove="" one="" endpoint.="" unit="roots[i]" =="=" ||="" roots[i]="==" ?="" 0.5="" :="" 1;="" x_="curve.quadraticAt(x0," x1,="" x2,="" roots[i]);="" if="" (x_="" x)="" quick="" reject="" continue;="" }="" (roots[i]="" t)="" +="y_" y0="" -unit;="" else="" return="" w;="" roots[0]="==" roots[0]);="" 0;="" y2="" todo="" arc="" 旋转="" function="" windingarc(cx,="" cy,="" r,="" startangle,="" endangle,="" anticlockwise,="" x,="" y)="" y="" -="cy;" (y=""> r || y &lt; -r) {
            return 0;
        }
        var tmp = Math.sqrt(r * r - y * y);
        roots[0] = -tmp;
        roots[1] = tmp;
        var diff = Math.abs(startAngle - endAngle);
        if (diff &lt; 0.0001) {
            return 0;
        }
        if (diff % PI2 &lt; 0.0001) {
            // Is a circle
            startAngle = 0;
            endAngle = PI2;
            var dir = anticlockwise ? 1 : -1;
            if (x &gt;= roots[0] + cx &amp;&amp; x <= roots[1]="" +="" cx)="" {="" return="" dir;="" }="" else="" 0;="" if="" (anticlockwise)="" var="" tmp="startAngle;" startangle="normalizeRadian(endAngle);" endangle="normalizeRadian(tmp);" (startangle=""> endAngle) {
            endAngle += PI2;
        }
        var w = 0;
        for (var i = 0; i &lt; 2; i++) {
            var x_ = roots[i];
            if (x_ + cx &gt; x) {
                var angle = Math.atan2(y, x_);
                var dir = anticlockwise ? 1 : -1;
                if (angle &lt; 0) {
                    angle = PI2 + angle;
                }
                if (angle &gt;= startAngle &amp;&amp; angle <= endangle="" ||="" angle="" +="" pi2="">= startAngle &amp;&amp; angle + PI2 <= endangle)="" {="" if="" (angle=""> Math.PI / 2 &amp;&amp; angle &lt; Math.PI * 1.5) {
                        dir = -dir;
                    }
                    w += dir;
                }
            }
        }
        return w;
    }
    function containPath(data, lineWidth, isStroke, x, y) {
        var w = 0;
        var xi = 0;
        var yi = 0;
        var x0 = 0;
        var y0 = 0;
        for (var i = 0; i &lt; data.length;) {
            var cmd = data[i++];
            // Begin a new subpath
            if (cmd === CMD.M &amp;&amp; i &gt; 1) {
                // Close previous subpath
                if (!isStroke) {
                    w += windingLine(xi, yi, x0, y0, x, y);
                }    // &#x5982;&#x679C;&#x88AB;&#x4EFB;&#x4F55;&#x4E00;&#x4E2A; subpath &#x5305;&#x542B;
                     // if (w !== 0) {
                     //     return true;
                     // }
            }
            if (i == 1) {
                // &#x5982;&#x679C;&#x7B2C;&#x4E00;&#x4E2A;&#x547D;&#x4EE4;&#x662F; L, C, Q
                // &#x5219; previous point &#x540C;&#x7ED8;&#x5236;&#x547D;&#x4EE4;&#x7684;&#x7B2C;&#x4E00;&#x4E2A; point
                //
                // &#x7B2C;&#x4E00;&#x4E2A;&#x547D;&#x4EE4;&#x4E3A; Arc &#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x4F1A;&#x5728;&#x540E;&#x9762;&#x7279;&#x6B8A;&#x5904;&#x7406;
                xi = data[i];
                yi = data[i + 1];
                x0 = xi;
                y0 = yi;
            }
            switch (cmd) {
            case CMD.M:
                // moveTo &#x547D;&#x4EE4;&#x91CD;&#x65B0;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x65B0;&#x7684; subpath, &#x5E76;&#x4E14;&#x66F4;&#x65B0;&#x65B0;&#x7684;&#x8D77;&#x70B9;
                // &#x5728; closePath &#x7684;&#x65F6;&#x5019;&#x4F7F;&#x7528;
                x0 = data[i++];
                y0 = data[i++];
                xi = x0;
                yi = y0;
                break;
            case CMD.L:
                if (isStroke) {
                    if (containStroke(xi, yi, data[i], data[i + 1], lineWidth, x, y)) {
                        return true;
                    }
                } else {
                    // NOTE &#x5728;&#x7B2C;&#x4E00;&#x4E2A;&#x547D;&#x4EE4;&#x4E3A; L, C, Q &#x7684;&#x65F6;&#x5019;&#x4F1A;&#x8BA1;&#x7B97;&#x51FA; NaN
                    w += windingLine(xi, yi, data[i], data[i + 1], x, y) || 0;
                }
                xi = data[i++];
                yi = data[i++];
                break;
            case CMD.C:
                if (isStroke) {
                    if (cubic.containStroke(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], lineWidth, x, y)) {
                        return true;
                    }
                } else {
                    w += windingCubic(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], x, y) || 0;
                }
                xi = data[i++];
                yi = data[i++];
                break;
            case CMD.Q:
                if (isStroke) {
                    if (quadratic.containStroke(xi, yi, data[i++], data[i++], data[i], data[i + 1], lineWidth, x, y)) {
                        return true;
                    }
                } else {
                    w += windingQuadratic(xi, yi, data[i++], data[i++], data[i], data[i + 1], x, y) || 0;
                }
                xi = data[i++];
                yi = data[i++];
                break;
            case CMD.A:
                // TODO Arc &#x5224;&#x65AD;&#x7684;&#x5F00;&#x9500;&#x6BD4;&#x8F83;&#x5927;
                var cx = data[i++];
                var cy = data[i++];
                var rx = data[i++];
                var ry = data[i++];
                var theta = data[i++];
                var dTheta = data[i++];
                // TODO Arc &#x65CB;&#x8F6C;
                var psi = data[i++];
                var anticlockwise = 1 - data[i++];
                var x1 = Math.cos(theta) * rx + cx;
                var y1 = Math.sin(theta) * ry + cy;
                // &#x4E0D;&#x662F;&#x76F4;&#x63A5;&#x4F7F;&#x7528; arc &#x547D;&#x4EE4;
                if (i &gt; 1) {
                    w += windingLine(xi, yi, x1, y1, x, y);
                } else {
                    // &#x7B2C;&#x4E00;&#x4E2A;&#x547D;&#x4EE4;&#x8D77;&#x70B9;&#x8FD8;&#x672A;&#x5B9A;&#x4E49;
                    x0 = x1;
                    y0 = y1;
                }
                // zr &#x4F7F;&#x7528;scale&#x6765;&#x6A21;&#x62DF;&#x692D;&#x5706;, &#x8FD9;&#x91CC;&#x4E5F;&#x5BF9;x&#x505A;&#x4E00;&#x5B9A;&#x7684;&#x7F29;&#x653E;
                var _x = (x - cx) * ry / rx + cx;
                if (isStroke) {
                    if (arc.containStroke(cx, cy, ry, theta, theta + dTheta, anticlockwise, lineWidth, _x, y)) {
                        return true;
                    }
                } else {
                    w += windingArc(cx, cy, ry, theta, theta + dTheta, anticlockwise, _x, y);
                }
                xi = Math.cos(theta + dTheta) * rx + cx;
                yi = Math.sin(theta + dTheta) * ry + cy;
                break;
            case CMD.R:
                x0 = xi = data[i++];
                y0 = yi = data[i++];
                var width = data[i++];
                var height = data[i++];
                var x1 = x0 + width;
                var y1 = y0 + height;
                if (isStroke) {
                    if (containStroke(x0, y0, x1, y0, lineWidth, x, y) || containStroke(x1, y0, x1, y1, lineWidth, x, y) || containStroke(x1, y1, x0, y1, lineWidth, x, y) || containStroke(x0, y1, x0, y0, lineWidth, x, y)) {
                        return true;
                    }
                } else {
                    // FIXME Clockwise ?
                    w += windingLine(x1, y0, x1, y1, x, y);
                    w += windingLine(x0, y1, x0, y0, x, y);
                }
                break;
            case CMD.Z:
                if (isStroke) {
                    if (containStroke(xi, yi, x0, y0, lineWidth, x, y)) {
                        return true;
                    }
                } else {
                    // Close a subpath
                    w += windingLine(xi, yi, x0, y0, x, y);    // &#x5982;&#x679C;&#x88AB;&#x4EFB;&#x4F55;&#x4E00;&#x4E2A; subpath &#x5305;&#x542B;
                                                               // FIXME subpaths may overlap
                                                               // if (w !== 0) {
                                                               //     return true;
                                                               // }
                }
                xi = x0;
                yi = y0;
                break;
            }
        }
        if (!isStroke &amp;&amp; !isAroundEqual(yi, y0)) {
            w += windingLine(xi, yi, x0, y0, x, y) || 0;
        }
        return w !== 0;
    }
    return {
        contain: function (pathData, x, y) {
            return containPath(pathData, 0, false, x, y);
        },
        containStroke: function (pathData, lineWidth, x, y) {
            return containPath(pathData, lineWidth, true, x, y);
        }
    };
});
define(&apos;zrender/graphic/Pattern&apos;, [&apos;require&apos;], function (require) {
    var Pattern = function (image, repeat) {
        this.image = image;
        this.repeat = repeat;
        // Can be cloned
        this.type = &apos;pattern&apos;;
    };
    Pattern.prototype.getCanvasPattern = function (ctx) {
        return this._canvasPattern || (this._canvasPattern = ctx.createPattern(this.image, this.repeat));
    };
    return Pattern;
});
define(&apos;zrender/graphic/Style&apos;, [&apos;require&apos;], function (require) {
    var STYLE_COMMON_PROPS = [
            [
                &apos;shadowBlur&apos;,
                0
            ],
            [
                &apos;shadowOffsetX&apos;,
                0
            ],
            [
                &apos;shadowOffsetY&apos;,
                0
            ],
            [
                &apos;shadowColor&apos;,
                &apos;#000&apos;
            ],
            [
                &apos;lineCap&apos;,
                &apos;butt&apos;
            ],
            [
                &apos;lineJoin&apos;,
                &apos;miter&apos;
            ],
            [
                &apos;miterLimit&apos;,
                10
            ]
        ];
    // var SHADOW_PROPS = STYLE_COMMON_PROPS.slice(0, 4);
    // var LINE_PROPS = STYLE_COMMON_PROPS.slice(4);
    var Style = function (opts) {
        this.extendFrom(opts);
    };
    function createLinearGradient(ctx, obj, rect) {
        // var size =
        var x = obj.x;
        var x2 = obj.x2;
        var y = obj.y;
        var y2 = obj.y2;
        if (!obj.global) {
            x = x * rect.width + rect.x;
            x2 = x2 * rect.width + rect.x;
            y = y * rect.height + rect.y;
            y2 = y2 * rect.height + rect.y;
        }
        var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);
        return canvasGradient;
    }
    function createRadialGradient(ctx, obj, rect) {
        var width = rect.width;
        var height = rect.height;
        var min = Math.min(width, height);
        var x = obj.x;
        var y = obj.y;
        var r = obj.r;
        if (!obj.global) {
            x = x * width + rect.x;
            y = y * height + rect.y;
            r = r * min;
        }
        var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);
        return canvasGradient;
    }
    Style.prototype = {
        constructor: Style,
        fill: &apos;#000000&apos;,
        stroke: null,
        opacity: 1,
        lineDash: null,
        lineDashOffset: 0,
        shadowBlur: 0,
        shadowOffsetX: 0,
        shadowOffsetY: 0,
        lineWidth: 1,
        strokeNoScale: false,
        text: null,
        textFill: &apos;#000&apos;,
        textStroke: null,
        textPosition: &apos;inside&apos;,
        textBaseline: null,
        textAlign: null,
        textVerticalAlign: null,
        textDistance: 5,
        textShadowBlur: 0,
        textShadowOffsetX: 0,
        textShadowOffsetY: 0,
        blend: null,
        bind: function (ctx, el, prevEl) {
            var style = this;
            var prevStyle = prevEl &amp;&amp; prevEl.style;
            var firstDraw = !prevStyle;
            for (var i = 0; i &lt; STYLE_COMMON_PROPS.length; i++) {
                var prop = STYLE_COMMON_PROPS[i];
                var styleName = prop[0];
                if (firstDraw || style[styleName] !== prevStyle[styleName]) {
                    // FIXME Invalid property value will cause style leak from previous element.
                    ctx[styleName] = style[styleName] || prop[1];
                }
            }
            if (firstDraw || style.fill !== prevStyle.fill) {
                ctx.fillStyle = style.fill;
            }
            if (firstDraw || style.stroke !== prevStyle.stroke) {
                ctx.strokeStyle = style.stroke;
            }
            if (firstDraw || style.opacity !== prevStyle.opacity) {
                ctx.globalAlpha = style.opacity == null ? 1 : style.opacity;
            }
            if (firstDraw || style.blend !== prevStyle.blend) {
                ctx.globalCompositeOperation = style.blend || &apos;source-over&apos;;
            }
            if (this.hasStroke()) {
                var lineWidth = style.lineWidth;
                ctx.lineWidth = lineWidth / (this.strokeNoScale &amp;&amp; el &amp;&amp; el.getLineScale ? el.getLineScale() : 1);
            }
        },
        hasFill: function () {
            var fill = this.fill;
            return fill != null &amp;&amp; fill !== &apos;none&apos;;
        },
        hasStroke: function () {
            var stroke = this.stroke;
            return stroke != null &amp;&amp; stroke !== &apos;none&apos; &amp;&amp; this.lineWidth &gt; 0;
        },
        extendFrom: function (otherStyle, overwrite) {
            if (otherStyle) {
                var target = this;
                for (var name in otherStyle) {
                    if (otherStyle.hasOwnProperty(name) &amp;&amp; (overwrite || !target.hasOwnProperty(name))) {
                        target[name] = otherStyle[name];
                    }
                }
            }
        },
        set: function (obj, value) {
            if (typeof obj === &apos;string&apos;) {
                this[obj] = value;
            } else {
                this.extendFrom(obj, true);
            }
        },
        clone: function () {
            var newStyle = new this.constructor();
            newStyle.extendFrom(this, true);
            return newStyle;
        },
        getGradient: function (ctx, obj, rect) {
            var method = obj.type === &apos;radial&apos; ? createRadialGradient : createLinearGradient;
            var canvasGradient = method(ctx, obj, rect);
            var colorStops = obj.colorStops;
            for (var i = 0; i &lt; colorStops.length; i++) {
                canvasGradient.addColorStop(colorStops[i].offset, colorStops[i].color);
            }
            return canvasGradient;
        }
    };
    var styleProto = Style.prototype;
    for (var i = 0; i &lt; STYLE_COMMON_PROPS.length; i++) {
        var prop = STYLE_COMMON_PROPS[i];
        if (!(prop[0] in styleProto)) {
            styleProto[prop[0]] = prop[1];
        }
    }
    // Provide for others
    Style.getGradient = styleProto.getGradient;
    return Style;
});
define(&apos;zrender/graphic/mixin/RectText&apos;, [&apos;require&apos;, &apos;../../contain/text&apos;, &apos;../../core/BoundingRect&apos;], function (require) {
    var textContain = require(&apos;../../contain/text&apos;);
    var BoundingRect = require(&apos;../../core/BoundingRect&apos;);
    var tmpRect = new BoundingRect();
    var RectText = function () {
    };
    function parsePercent(value, maxValue) {
        if (typeof value === &apos;string&apos;) {
            if (value.lastIndexOf(&apos;%&apos;) &gt;= 0) {
                return parseFloat(value) / 100 * maxValue;
            }
            return parseFloat(value);
        }
        return value;
    }
    function setTransform(ctx, m) {
        ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
    }
    RectText.prototype = {
        constructor: RectText,
        drawRectText: function (ctx, rect, textRect) {
            var style = this.style;
            var text = style.text;
            // Convert to string
            text != null &amp;&amp; (text += &apos;&apos;);
            if (!text) {
                return;
            }
            // FIXME
            ctx.save();
            var x;
            var y;
            var textPosition = style.textPosition;
            var distance = style.textDistance;
            var align = style.textAlign;
            var font = style.textFont || style.font;
            var baseline = style.textBaseline;
            var verticalAlign = style.textVerticalAlign;
            textRect = textRect || textContain.getBoundingRect(text, font, align, baseline);
            // Transform rect to view space
            var transform = this.transform;
            if (transform) {
                tmpRect.copy(rect);
                tmpRect.applyTransform(transform);
                rect = tmpRect;
            }
            // Text position represented by coord
            if (textPosition instanceof Array) {
                // Percent
                x = rect.x + parsePercent(textPosition[0], rect.width);
                y = rect.y + parsePercent(textPosition[1], rect.height);
                align = align || &apos;left&apos;;
                baseline = baseline || &apos;top&apos;;
                if (verticalAlign) {
                    switch (verticalAlign) {
                    case &apos;middle&apos;:
                        y -= textRect.height / 2 - textRect.lineHeight / 2;
                        break;
                    case &apos;bottom&apos;:
                        y -= textRect.height - textRect.lineHeight / 2;
                        break;
                    default:
                        y += textRect.lineHeight / 2;
                    }
                    // Force bseline to be middle
                    baseline = &apos;middle&apos;;
                }
            } else {
                var res = textContain.adjustTextPositionOnRect(textPosition, rect, textRect, distance);
                x = res.x;
                y = res.y;
                // Default align and baseline when has textPosition
                align = align || res.textAlign;
                baseline = baseline || res.textBaseline;
            }
            // Use canvas default left textAlign. Giving invalid value will cause state not change
            ctx.textAlign = align || &apos;left&apos;;
            // Use canvas default alphabetic baseline
            ctx.textBaseline = baseline || &apos;alphabetic&apos;;
            var textFill = style.textFill;
            var textStroke = style.textStroke;
            textFill &amp;&amp; (ctx.fillStyle = textFill);
            textStroke &amp;&amp; (ctx.strokeStyle = textStroke);
            ctx.font = font;
            // Text shadow
            // Always set shadowBlur and shadowOffset to avoid leak from displayable
            ctx.shadowBlur = style.textShadowBlur;
            ctx.shadowColor = style.textShadowColor || &apos;transparent&apos;;
            ctx.shadowOffsetX = style.textShadowOffsetX;
            ctx.shadowOffsetY = style.textShadowOffsetY;
            var textLines = text.split(&apos;\n&apos;);
            for (var i = 0; i &lt; textLines.length; i++) {
                textFill &amp;&amp; ctx.fillText(textLines[i], x, y);
                textStroke &amp;&amp; ctx.strokeText(textLines[i], x, y);
                y += textRect.lineHeight;
            }
            ctx.restore();
        }
    };
    return RectText;
});
define(&apos;zrender/core/curve&apos;, [&apos;require&apos;, &apos;./vector&apos;], function (require) {
    &apos;use strict&apos;;
    var vec2 = require(&apos;./vector&apos;);
    var v2Create = vec2.create;
    var v2DistSquare = vec2.distSquare;
    var mathPow = Math.pow;
    var mathSqrt = Math.sqrt;
    var EPSILON = 1e-8;
    var EPSILON_NUMERIC = 0.0001;
    var THREE_SQRT = mathSqrt(3);
    var ONE_THIRD = 1 / 3;
    // &#x4E34;&#x65F6;&#x53D8;&#x91CF;
    var _v0 = v2Create();
    var _v1 = v2Create();
    var _v2 = v2Create();
    // var _v3 = vec2.create();
    function isAroundZero(val) {
        return val &gt; -EPSILON &amp;&amp; val &lt; EPSILON;
    }
    function isNotAroundZero(val) {
        return val &gt; EPSILON || val &lt; -EPSILON;
    }
    /**
     * &#x8BA1;&#x7B97;&#x4E09;&#x6B21;&#x8D1D;&#x585E;&#x5C14;&#x503C;
     * @memberOf module:zrender/core/curve
     * @param  {number} p0
     * @param  {number} p1
     * @param  {number} p2
     * @param  {number} p3
     * @param  {number} t
     * @return {number}
     */
    function cubicAt(p0, p1, p2, p3, t) {
        var onet = 1 - t;
        return onet * onet * (onet * p0 + 3 * t * p1) + t * t * (t * p3 + 3 * onet * p2);
    }
    /**
     * &#x8BA1;&#x7B97;&#x4E09;&#x6B21;&#x8D1D;&#x585E;&#x5C14;&#x5BFC;&#x6570;&#x503C;
     * @memberOf module:zrender/core/curve
     * @param  {number} p0
     * @param  {number} p1
     * @param  {number} p2
     * @param  {number} p3
     * @param  {number} t
     * @return {number}
     */
    function cubicDerivativeAt(p0, p1, p2, p3, t) {
        var onet = 1 - t;
        return 3 * (((p1 - p0) * onet + 2 * (p2 - p1) * t) * onet + (p3 - p2) * t * t);
    }
    /**
     * &#x8BA1;&#x7B97;&#x4E09;&#x6B21;&#x8D1D;&#x585E;&#x5C14;&#x65B9;&#x7A0B;&#x6839;&#xFF0C;&#x4F7F;&#x7528;&#x76DB;&#x91D1;&#x516C;&#x5F0F;
     * @memberOf module:zrender/core/curve
     * @param  {number} p0
     * @param  {number} p1
     * @param  {number} p2
     * @param  {number} p3
     * @param  {number} val
     * @param  {Array.<number>} roots
     * @return {number} &#x6709;&#x6548;&#x6839;&#x6570;&#x76EE;
     */
    function cubicRootAt(p0, p1, p2, p3, val, roots) {
        // Evaluate roots of cubic functions
        var a = p3 + 3 * (p1 - p2) - p0;
        var b = 3 * (p2 - p1 * 2 + p0);
        var c = 3 * (p1 - p0);
        var d = p0 - val;
        var A = b * b - 3 * a * c;
        var B = b * c - 9 * a * d;
        var C = c * c - 3 * b * d;
        var n = 0;
        if (isAroundZero(A) &amp;&amp; isAroundZero(B)) {
            if (isAroundZero(b)) {
                roots[0] = 0;
            } else {
                var t1 = -c / b;
                //t1, t2, t3, b is not zero
                if (t1 &gt;= 0 &amp;&amp; t1 <= 4="" 1)="" {="" roots[n++]="t1;" }="" else="" var="" disc="B" *="" b="" -="" a="" c;="" if="" (isaroundzero(disc))="" k="B" a;="" t1="-b" +="" k;="" t1,="" is="" not="" zero="" t2="-K" 2;="" t2,="" t3="" (t1="">= 0 &amp;&amp; t1 <= 1)="" {="" roots[n++]="t1;" }="" if="" (t2="">= 0 &amp;&amp; t2 <= 1)="" {="" roots[n++]="t2;" }="" else="" if="" (disc=""> 0) {
                var discSqrt = mathSqrt(disc);
                var Y1 = A * b + 1.5 * a * (-B + discSqrt);
                var Y2 = A * b + 1.5 * a * (-B - discSqrt);
                if (Y1 &lt; 0) {
                    Y1 = -mathPow(-Y1, ONE_THIRD);
                } else {
                    Y1 = mathPow(Y1, ONE_THIRD);
                }
                if (Y2 &lt; 0) {
                    Y2 = -mathPow(-Y2, ONE_THIRD);
                } else {
                    Y2 = mathPow(Y2, ONE_THIRD);
                }
                var t1 = (-b - (Y1 + Y2)) / (3 * a);
                if (t1 &gt;= 0 &amp;&amp; t1 <= 2="" 3="" 1)="" {="" roots[n++]="t1;" }="" else="" var="" t="(2" *="" a="" b="" -="" b)="" (2="" mathsqrt(a="" a));="" theta="Math.acos(T)" 3;="" asqrt="mathSqrt(A);" tmp="Math.cos(theta);" t1="(-b" tmp)="" (3="" a);="" t2="(-b" +="" (tmp="" three_sqrt="" math.sin(theta)))="" t3="(-b" if="" (t1="">= 0 &amp;&amp; t1 <= 1)="" {="" roots[n++]="t1;" }="" if="" (t2="">= 0 &amp;&amp; t2 <= 1)="" {="" roots[n++]="t2;" }="" if="" (t3="">= 0 &amp;&amp; t3 <= 1)="" {="" roots[n++]="t3;" }="" return="" n;="" **="" *="" 计算三次贝塞尔方程极限值的位置="" @memberof="" module:zrender="" core="" curve="" @param="" {number}="" p0="" p1="" p2="" p3="" {array.<number="">} extrema
     * @return {number} &#x6709;&#x6548;&#x6570;&#x76EE;
     */
    function cubicExtrema(p0, p1, p2, p3, extrema) {
        var b = 6 * p2 - 12 * p1 + 6 * p0;
        var a = 9 * p1 + 3 * p3 - 3 * p0 - 9 * p2;
        var c = 3 * p1 - 3 * p0;
        var n = 0;
        if (isAroundZero(a)) {
            if (isNotAroundZero(b)) {
                var t1 = -c / b;
                if (t1 &gt;= 0 &amp;&amp; t1 <= 4="" 1)="" {="" extrema[n++]="t1;" }="" else="" var="" disc="b" *="" b="" -="" a="" c;="" if="" (isaroundzero(disc))="" extrema[0]="-b" (2="" a);="" (disc=""> 0) {
                var discSqrt = mathSqrt(disc);
                var t1 = (-b + discSqrt) / (2 * a);
                var t2 = (-b - discSqrt) / (2 * a);
                if (t1 &gt;= 0 &amp;&amp; t1 <= 1)="" {="" extrema[n++]="t1;" }="" if="" (t2="">= 0 &amp;&amp; t2 <= 1)="" {="" extrema[n++]="t2;" }="" return="" n;="" **="" *="" 细分三次贝塞尔曲线="" @memberof="" module:zrender="" core="" curve="" @param="" {number}="" p0="" p1="" p2="" p3="" t="" {array.<number="">} out
     */
    function cubicSubdivide(p0, p1, p2, p3, t, out) {
        var p01 = (p1 - p0) * t + p0;
        var p12 = (p2 - p1) * t + p1;
        var p23 = (p3 - p2) * t + p2;
        var p012 = (p12 - p01) * t + p01;
        var p123 = (p23 - p12) * t + p12;
        var p0123 = (p123 - p012) * t + p012;
        // Seg0
        out[0] = p0;
        out[1] = p01;
        out[2] = p012;
        out[3] = p0123;
        // Seg1
        out[4] = p0123;
        out[5] = p123;
        out[6] = p23;
        out[7] = p3;
    }
    /**
     * &#x6295;&#x5C04;&#x70B9;&#x5230;&#x4E09;&#x6B21;&#x8D1D;&#x585E;&#x5C14;&#x66F2;&#x7EBF;&#x4E0A;&#xFF0C;&#x8FD4;&#x56DE;&#x6295;&#x5C04;&#x8DDD;&#x79BB;&#x3002;
     * &#x6295;&#x5C04;&#x70B9;&#x6709;&#x53EF;&#x80FD;&#x4F1A;&#x6709;&#x4E00;&#x4E2A;&#x6216;&#x8005;&#x591A;&#x4E2A;&#xFF0C;&#x8FD9;&#x91CC;&#x53EA;&#x8FD4;&#x56DE;&#x5176;&#x4E2D;&#x8DDD;&#x79BB;&#x6700;&#x77ED;&#x7684;&#x4E00;&#x4E2A;&#x3002;
     * @param {number} x0
     * @param {number} y0
     * @param {number} x1
     * @param {number} y1
     * @param {number} x2
     * @param {number} y2
     * @param {number} x3
     * @param {number} y3
     * @param {number} x
     * @param {number} y
     * @param {Array.<number>} [out] &#x6295;&#x5C04;&#x70B9;
     * @return {number}
     */
    function cubicProjectPoint(x0, y0, x1, y1, x2, y2, x3, y3, x, y, out) {
        // http://pomax.github.io/bezierinfo/#projections
        var t;
        var interval = 0.005;
        var d = Infinity;
        var prev;
        var next;
        var d1;
        var d2;
        _v0[0] = x;
        _v0[1] = y;
        // &#x5148;&#x7C97;&#x7565;&#x4F30;&#x8BA1;&#x4E00;&#x4E0B;&#x53EF;&#x80FD;&#x7684;&#x6700;&#x5C0F;&#x8DDD;&#x79BB;&#x7684; t &#x503C;
        // PENDING
        for (var _t = 0; _t &lt; 1; _t += 0.05) {
            _v1[0] = cubicAt(x0, x1, x2, x3, _t);
            _v1[1] = cubicAt(y0, y1, y2, y3, _t);
            d1 = v2DistSquare(_v0, _v1);
            if (d1 &lt; d) {
                t = _t;
                d = d1;
            }
        }
        d = Infinity;
        // At most 32 iteration
        for (var i = 0; i &lt; 32; i++) {
            if (interval &lt; EPSILON_NUMERIC) {
                break;
            }
            prev = t - interval;
            next = t + interval;
            // t - interval
            _v1[0] = cubicAt(x0, x1, x2, x3, prev);
            _v1[1] = cubicAt(y0, y1, y2, y3, prev);
            d1 = v2DistSquare(_v1, _v0);
            if (prev &gt;= 0 &amp;&amp; d1 &lt; d) {
                t = prev;
                d = d1;
            } else {
                // t + interval
                _v2[0] = cubicAt(x0, x1, x2, x3, next);
                _v2[1] = cubicAt(y0, y1, y2, y3, next);
                d2 = v2DistSquare(_v2, _v0);
                if (next <= 1="" 2="" &&="" d2="" <="" d)="" {="" t="next;" d="d2;" }="" else="" interval="" *="0.5;" if="" (out)="" out[0]="cubicAt(x0," x1,="" x2,="" x3,="" t);="" out[1]="cubicAt(y0," y1,="" y2,="" y3,="" console.log(interval,="" i);="" return="" mathsqrt(d);="" **="" 计算二次方贝塞尔值="" @param="" {number}="" p0="" p1="" p2="" @return="" function="" quadraticat(p0,="" p1,="" p2,="" t)="" var="" onet="1" -="" t;="" (onet="" +="" p1)="" p2;="" 计算二次方贝塞尔导数值="" quadraticderivativeat(p0,="" ((1="" (p1="" p0)="" (p2="" p1));="" 计算二次方贝塞尔方程根="" {array.<number="">} roots
     * @return {number} &#x6709;&#x6548;&#x6839;&#x6570;&#x76EE;
     */
    function quadraticRootAt(p0, p1, p2, val, roots) {
        var a = p0 - 2 * p1 + p2;
        var b = 2 * (p1 - p0);
        var c = p0 - val;
        var n = 0;
        if (isAroundZero(a)) {
            if (isNotAroundZero(b)) {
                var t1 = -c / b;
                if (t1 &gt;= 0 &amp;&amp; t1 <= 4="" 1)="" {="" roots[n++]="t1;" }="" else="" var="" disc="b" *="" b="" -="" a="" c;="" if="" (isaroundzero(disc))="" t1="-b" (2="" a);="" (t1="">= 0 &amp;&amp; t1 <= 1)="" {="" roots[n++]="t1;" }="" else="" if="" (disc=""> 0) {
                var discSqrt = mathSqrt(disc);
                var t1 = (-b + discSqrt) / (2 * a);
                var t2 = (-b - discSqrt) / (2 * a);
                if (t1 &gt;= 0 &amp;&amp; t1 <= 1)="" {="" roots[n++]="t1;" }="" if="" (t2="">= 0 &amp;&amp; t2 <= 2="" 1)="" {="" roots[n++]="t2;" }="" return="" n;="" **="" *="" 计算二次贝塞尔方程极限值="" @memberof="" module:zrender="" core="" curve="" @param="" {number}="" p0="" p1="" p2="" @return="" function="" quadraticextremum(p0,="" p1,="" p2)="" var="" divider="p0" +="" -="" p1;="" if="" (divider="==" 0)="" is="" center="" of="" and="" 0.5;="" else="" (p0="" p1)="" divider;="" 细分二次贝塞尔曲线="" t="" {array.<number="">} out
     */
    function quadraticSubdivide(p0, p1, p2, t, out) {
        var p01 = (p1 - p0) * t + p0;
        var p12 = (p2 - p1) * t + p1;
        var p012 = (p12 - p01) * t + p01;
        // Seg0
        out[0] = p0;
        out[1] = p01;
        out[2] = p012;
        // Seg1
        out[3] = p012;
        out[4] = p12;
        out[5] = p2;
    }
    /**
     * &#x6295;&#x5C04;&#x70B9;&#x5230;&#x4E8C;&#x6B21;&#x8D1D;&#x585E;&#x5C14;&#x66F2;&#x7EBF;&#x4E0A;&#xFF0C;&#x8FD4;&#x56DE;&#x6295;&#x5C04;&#x8DDD;&#x79BB;&#x3002;
     * &#x6295;&#x5C04;&#x70B9;&#x6709;&#x53EF;&#x80FD;&#x4F1A;&#x6709;&#x4E00;&#x4E2A;&#x6216;&#x8005;&#x591A;&#x4E2A;&#xFF0C;&#x8FD9;&#x91CC;&#x53EA;&#x8FD4;&#x56DE;&#x5176;&#x4E2D;&#x8DDD;&#x79BB;&#x6700;&#x77ED;&#x7684;&#x4E00;&#x4E2A;&#x3002;
     * @param {number} x0
     * @param {number} y0
     * @param {number} x1
     * @param {number} y1
     * @param {number} x2
     * @param {number} y2
     * @param {number} x
     * @param {number} y
     * @param {Array.<number>} out &#x6295;&#x5C04;&#x70B9;
     * @return {number}
     */
    function quadraticProjectPoint(x0, y0, x1, y1, x2, y2, x, y, out) {
        // http://pomax.github.io/bezierinfo/#projections
        var t;
        var interval = 0.005;
        var d = Infinity;
        _v0[0] = x;
        _v0[1] = y;
        // &#x5148;&#x7C97;&#x7565;&#x4F30;&#x8BA1;&#x4E00;&#x4E0B;&#x53EF;&#x80FD;&#x7684;&#x6700;&#x5C0F;&#x8DDD;&#x79BB;&#x7684; t &#x503C;
        // PENDING
        for (var _t = 0; _t &lt; 1; _t += 0.05) {
            _v1[0] = quadraticAt(x0, x1, x2, _t);
            _v1[1] = quadraticAt(y0, y1, y2, _t);
            var d1 = v2DistSquare(_v0, _v1);
            if (d1 &lt; d) {
                t = _t;
                d = d1;
            }
        }
        d = Infinity;
        // At most 32 iteration
        for (var i = 0; i &lt; 32; i++) {
            if (interval &lt; EPSILON_NUMERIC) {
                break;
            }
            var prev = t - interval;
            var next = t + interval;
            // t - interval
            _v1[0] = quadraticAt(x0, x1, x2, prev);
            _v1[1] = quadraticAt(y0, y1, y2, prev);
            var d1 = v2DistSquare(_v1, _v0);
            if (prev &gt;= 0 &amp;&amp; d1 &lt; d) {
                t = prev;
                d = d1;
            } else {
                // t + interval
                _v2[0] = quadraticAt(x0, x1, x2, next);
                _v2[1] = quadraticAt(y0, y1, y2, next);
                var d2 = v2DistSquare(_v2, _v0);
                if (next <= 1="" &&="" d2="" <="" d)="" {="" t="next;" d="d2;" }="" else="" interval="" *="0.5;" if="" (out)="" out[0]="quadraticAt(x0," x1,="" x2,="" t);="" out[1]="quadraticAt(y0," y1,="" y2,="" console.log(interval,="" i);="" return="" mathsqrt(d);="" cubicat:="" cubicat,="" cubicderivativeat:="" cubicderivativeat,="" cubicrootat:="" cubicrootat,="" cubicextrema:="" cubicextrema,="" cubicsubdivide:="" cubicsubdivide,="" cubicprojectpoint:="" cubicprojectpoint,="" quadraticat:="" quadraticat,="" quadraticderivativeat:="" quadraticderivativeat,="" quadraticrootat:="" quadraticrootat,="" quadraticextremum:="" quadraticextremum,="" quadraticsubdivide:="" quadraticsubdivide,="" quadraticprojectpoint:="" quadraticprojectpoint="" };="" });="" define('zrender="" core="" bbox',="" ['require',="" '.="" vector',="" curve'],="" function="" (require)="" var="" vec2="require(&apos;./vector&apos;);" curve="require(&apos;./curve&apos;);" bbox="{};" mathmin="Math.min;" mathmax="Math.max;" mathsin="Math.sin;" mathcos="Math.cos;" start="vec2.create();" end="vec2.create();" extremity="vec2.create();" pi2="Math.PI" 2;="" **="" 从顶点数组中计算出最小包围盒，写入`min`和`max`中="" @module="" zrender="" @param="" {array<object="">} points &#x9876;&#x70B9;&#x6570;&#x7EC4;
     * @param {number} min
     * @param {number} max
     */
    bbox.fromPoints = function (points, min, max) {
        if (points.length === 0) {
            return;
        }
        var p = points[0];
        var left = p[0];
        var right = p[0];
        var top = p[1];
        var bottom = p[1];
        var i;
        for (i = 1; i &lt; points.length; i++) {
            p = points[i];
            left = mathMin(left, p[0]);
            right = mathMax(right, p[0]);
            top = mathMin(top, p[1]);
            bottom = mathMax(bottom, p[1]);
        }
        min[0] = left;
        min[1] = top;
        max[0] = right;
        max[1] = bottom;
    };
    /**
     * @memberOf module:zrender/core/bbox
     * @param {number} x0
     * @param {number} y0
     * @param {number} x1
     * @param {number} y1
     * @param {Array.<number>} min
     * @param {Array.<number>} max
     */
    bbox.fromLine = function (x0, y0, x1, y1, min, max) {
        min[0] = mathMin(x0, x1);
        min[1] = mathMin(y0, y1);
        max[0] = mathMax(x0, x1);
        max[1] = mathMax(y0, y1);
    };
    var xDim = [];
    var yDim = [];
    /**
     * &#x4ECE;&#x4E09;&#x9636;&#x8D1D;&#x585E;&#x5C14;&#x66F2;&#x7EBF;(p0, p1, p2, p3)&#x4E2D;&#x8BA1;&#x7B97;&#x51FA;&#x6700;&#x5C0F;&#x5305;&#x56F4;&#x76D2;&#xFF0C;&#x5199;&#x5165;`min`&#x548C;`max`&#x4E2D;
     * @memberOf module:zrender/core/bbox
     * @param {number} x0
     * @param {number} y0
     * @param {number} x1
     * @param {number} y1
     * @param {number} x2
     * @param {number} y2
     * @param {number} x3
     * @param {number} y3
     * @param {Array.<number>} min
     * @param {Array.<number>} max
     */
    bbox.fromCubic = function (x0, y0, x1, y1, x2, y2, x3, y3, min, max) {
        var cubicExtrema = curve.cubicExtrema;
        var cubicAt = curve.cubicAt;
        var i;
        var n = cubicExtrema(x0, x1, x2, x3, xDim);
        min[0] = Infinity;
        min[1] = Infinity;
        max[0] = -Infinity;
        max[1] = -Infinity;
        for (i = 0; i &lt; n; i++) {
            var x = cubicAt(x0, x1, x2, x3, xDim[i]);
            min[0] = mathMin(x, min[0]);
            max[0] = mathMax(x, max[0]);
        }
        n = cubicExtrema(y0, y1, y2, y3, yDim);
        for (i = 0; i &lt; n; i++) {
            var y = cubicAt(y0, y1, y2, y3, yDim[i]);
            min[1] = mathMin(y, min[1]);
            max[1] = mathMax(y, max[1]);
        }
        min[0] = mathMin(x0, min[0]);
        max[0] = mathMax(x0, max[0]);
        min[0] = mathMin(x3, min[0]);
        max[0] = mathMax(x3, max[0]);
        min[1] = mathMin(y0, min[1]);
        max[1] = mathMax(y0, max[1]);
        min[1] = mathMin(y3, min[1]);
        max[1] = mathMax(y3, max[1]);
    };
    /**
     * &#x4ECE;&#x4E8C;&#x9636;&#x8D1D;&#x585E;&#x5C14;&#x66F2;&#x7EBF;(p0, p1, p2)&#x4E2D;&#x8BA1;&#x7B97;&#x51FA;&#x6700;&#x5C0F;&#x5305;&#x56F4;&#x76D2;&#xFF0C;&#x5199;&#x5165;`min`&#x548C;`max`&#x4E2D;
     * @memberOf module:zrender/core/bbox
     * @param {number} x0
     * @param {number} y0
     * @param {number} x1
     * @param {number} y1
     * @param {number} x2
     * @param {number} y2
     * @param {Array.<number>} min
     * @param {Array.<number>} max
     */
    bbox.fromQuadratic = function (x0, y0, x1, y1, x2, y2, min, max) {
        var quadraticExtremum = curve.quadraticExtremum;
        var quadraticAt = curve.quadraticAt;
        // Find extremities, where derivative in x dim or y dim is zero
        var tx = mathMax(mathMin(quadraticExtremum(x0, x1, x2), 1), 0);
        var ty = mathMax(mathMin(quadraticExtremum(y0, y1, y2), 1), 0);
        var x = quadraticAt(x0, x1, x2, tx);
        var y = quadraticAt(y0, y1, y2, ty);
        min[0] = mathMin(x0, x2, x);
        min[1] = mathMin(y0, y2, y);
        max[0] = mathMax(x0, x2, x);
        max[1] = mathMax(y0, y2, y);
    };
    /**
     * &#x4ECE;&#x5706;&#x5F27;&#x4E2D;&#x8BA1;&#x7B97;&#x51FA;&#x6700;&#x5C0F;&#x5305;&#x56F4;&#x76D2;&#xFF0C;&#x5199;&#x5165;`min`&#x548C;`max`&#x4E2D;
     * @method
     * @memberOf module:zrender/core/bbox
     * @param {number} x
     * @param {number} y
     * @param {number} rx
     * @param {number} ry
     * @param {number} startAngle
     * @param {number} endAngle
     * @param {number} anticlockwise
     * @param {Array.<number>} min
     * @param {Array.<number>} max
     */
    bbox.fromArc = function (x, y, rx, ry, startAngle, endAngle, anticlockwise, min, max) {
        var vec2Min = vec2.min;
        var vec2Max = vec2.max;
        var diff = Math.abs(startAngle - endAngle);
        if (diff % PI2 &lt; 0.0001 &amp;&amp; diff &gt; 0.0001) {
            // Is a circle
            min[0] = x - rx;
            min[1] = y - ry;
            max[0] = x + rx;
            max[1] = y + ry;
            return;
        }
        start[0] = mathCos(startAngle) * rx + x;
        start[1] = mathSin(startAngle) * ry + y;
        end[0] = mathCos(endAngle) * rx + x;
        end[1] = mathSin(endAngle) * ry + y;
        vec2Min(min, start, end);
        vec2Max(max, start, end);
        // Thresh to [0, Math.PI * 2]
        startAngle = startAngle % PI2;
        if (startAngle &lt; 0) {
            startAngle = startAngle + PI2;
        }
        endAngle = endAngle % PI2;
        if (endAngle &lt; 0) {
            endAngle = endAngle + PI2;
        }
        if (startAngle &gt; endAngle &amp;&amp; !anticlockwise) {
            endAngle += PI2;
        } else if (startAngle &lt; endAngle &amp;&amp; anticlockwise) {
            startAngle += PI2;
        }
        if (anticlockwise) {
            var tmp = endAngle;
            endAngle = startAngle;
            startAngle = tmp;
        }
        // var number = 0;
        // var step = (anticlockwise ? -Math.PI : Math.PI) / 2;
        for (var angle = 0; angle &lt; endAngle; angle += Math.PI / 2) {
            if (angle &gt; startAngle) {
                extremity[0] = mathCos(angle) * rx + x;
                extremity[1] = mathSin(angle) * ry + y;
                vec2Min(min, extremity, min);
                vec2Max(max, extremity, max);
            }
        }
    };
    return bbox;
});
define(&apos;zrender/contain/arc&apos;, [&apos;require&apos;, &apos;./util&apos;], function (require) {
    var normalizeRadian = require(&apos;./util&apos;).normalizeRadian;
    var PI2 = Math.PI * 2;
    return {
        containStroke: function (cx, cy, r, startAngle, endAngle, anticlockwise, lineWidth, x, y) {
            if (lineWidth === 0) {
                return false;
            }
            var _l = lineWidth;
            x -= cx;
            y -= cy;
            var d = Math.sqrt(x * x + y * y);
            if (d - _l &gt; r || d + _l &lt; r) {
                return false;
            }
            if (Math.abs(startAngle - endAngle) % PI2 &lt; 0.0001) {
                // Is a circle
                return true;
            }
            if (anticlockwise) {
                var tmp = startAngle;
                startAngle = normalizeRadian(endAngle);
                endAngle = normalizeRadian(tmp);
            } else {
                startAngle = normalizeRadian(startAngle);
                endAngle = normalizeRadian(endAngle);
            }
            if (startAngle &gt; endAngle) {
                endAngle += PI2;
            }
            var angle = Math.atan2(y, x);
            if (angle &lt; 0) {
                angle += PI2;
            }
            return angle &gt;= startAngle &amp;&amp; angle <= endangle="" ||="" angle="" +="" pi2="">= startAngle &amp;&amp; angle + PI2 <= endangle;="" }="" };="" });="" define('zrender="" contain="" windingline',="" [],="" function="" ()="" {="" return="" windingline(x0,="" y0,="" x1,="" y1,="" x,="" y)="" if="" (y=""> y0 &amp;&amp; y &gt; y1 || y &lt; y0 &amp;&amp; y &lt; y1) {
            return 0;
        }
        // Ignore horizontal line
        if (y1 === y0) {
            return 0;
        }
        var dir = y1 &lt; y0 ? 1 : -1;
        var t = (y - y0) / (y1 - y0);
        // Avoid winding error when intersection point is the connect point of two line of polygon
        if (t === 1 || t === 0) {
            dir = y1 &lt; y0 ? 0.5 : -0.5;
        }
        var x_ = t * (x1 - x0) + x0;
        return x_ &gt; x ? dir : 0;
    };
});
define(&apos;zrender/contain/line&apos;, [], function () {
    return {
        containStroke: function (x0, y0, x1, y1, lineWidth, x, y) {
            if (lineWidth === 0) {
                return false;
            }
            var _l = lineWidth;
            var _a = 0;
            var _b = x0;
            // Quick reject
            if (y &gt; y0 + _l &amp;&amp; y &gt; y1 + _l || y &lt; y0 - _l &amp;&amp; y &lt; y1 - _l || x &gt; x0 + _l &amp;&amp; x &gt; x1 + _l || x &lt; x0 - _l &amp;&amp; x &lt; x1 - _l) {
                return false;
            }
            if (x0 !== x1) {
                _a = (y0 - y1) / (x0 - x1);
                _b = (x0 * y1 - x1 * y0) / (x0 - x1);
            } else {
                return Math.abs(x - x0) <= 2="" _l="" 2;="" }="" var="" tmp="_a" *="" x="" -="" y="" +="" _b;="" _s="tmp" (_a="" _a="" 1);="" return="" <="_l" };="" });="" define('zrender="" contain="" cubic',="" ['require',="" '..="" core="" curve'],="" function="" (require)="" {="" curve="require(&apos;../core/curve&apos;);" containstroke:="" (x0,="" y0,="" x1,="" y1,="" x2,="" y2,="" x3,="" y3,="" linewidth,="" x,="" y)="" if="" (linewidth="==" 0)="" false;="" quick="" reject="" (y=""> y0 + _l &amp;&amp; y &gt; y1 + _l &amp;&amp; y &gt; y2 + _l &amp;&amp; y &gt; y3 + _l || y &lt; y0 - _l &amp;&amp; y &lt; y1 - _l &amp;&amp; y &lt; y2 - _l &amp;&amp; y &lt; y3 - _l || x &gt; x0 + _l &amp;&amp; x &gt; x1 + _l &amp;&amp; x &gt; x2 + _l &amp;&amp; x &gt; x3 + _l || x &lt; x0 - _l &amp;&amp; x &lt; x1 - _l &amp;&amp; x &lt; x2 - _l &amp;&amp; x &lt; x3 - _l) {
                return false;
            }
            var d = curve.cubicProjectPoint(x0, y0, x1, y1, x2, y2, x3, y3, x, y, null);
            return d <= _l="" 2;="" }="" };="" });="" define('zrender="" contain="" quadratic',="" ['require',="" '..="" core="" curve'],="" function="" (require)="" {="" var="" curve="require(&apos;../core/curve&apos;);" return="" containstroke:="" (x0,="" y0,="" x1,="" y1,="" x2,="" y2,="" linewidth,="" x,="" y)="" if="" (linewidth="==" 0)="" false;="" quick="" reject="" (y=""> y0 + _l &amp;&amp; y &gt; y1 + _l &amp;&amp; y &gt; y2 + _l || y &lt; y0 - _l &amp;&amp; y &lt; y1 - _l &amp;&amp; y &lt; y2 - _l || x &gt; x0 + _l &amp;&amp; x &gt; x1 + _l &amp;&amp; x &gt; x2 + _l || x &lt; x0 - _l &amp;&amp; x &lt; x1 - _l &amp;&amp; x &lt; x2 - _l) {
                return false;
            }
            var d = curve.quadraticProjectPoint(x0, y0, x1, y1, x2, y2, x, y, null);
            return d <= _l="" 2;="" }="" };="" });="" define('zrender="" contain="" util',="" ['require'],="" function="" (require)="" {="" var="" pi2="Math.PI" *="" return="" normalizeradian:="" (angle)="" angle="" %="PI2;" if="" (angle="" <="" 0)="" +="PI2;" angle;="" core="" lru',="" **="" simple="" double="" linked="" list.="" compared="" with="" array,="" it="" has="" o(1)="" remove="" operation.="" @constructor="" linkedlist="function" ()="" @type="" {module:zrender="" lru~entry}="" this.head="null;" this.tail="null;" this._len="0;" linkedlistproto="LinkedList.prototype;" insert="" a="" new="" value="" at="" the="" tail="" @param="" {}="" val="" @return="" linkedlistproto.insert="function" (val)="" entry="new" entry(val);="" this.insertentry(entry);="" entry;="" an="" linkedlistproto.insertentry="function" (entry)="" (!this.head)="" =="" else="" this.tail.next="entry;" entry.prev="this.tail;" this._len++;="" entry.="" linkedlistproto.remove="function" prev="entry.prev;" next="entry.next;" (prev)="" prev.next="next;" is="" head="" (next)="" next.prev="prev;" entry.next="entry.prev" null;="" this._len--;="" {number}="" linkedlistproto.len="function" this._len;="" this.value="val;" this.next;="" this.prev;="" lru="" cache="" @alias="" module:zrender="" (maxsize)="" this._list="new" linkedlist();="" this._map="{};" this._maxsize="maxSize" ||="" 10;="" lruproto="LRU.prototype;" {string}="" key="" lruproto.put="function" (key,="" value)="" list="this._list;" map="this._map;" (map[key]="=" null)="" len="list.len();" (len="">= this._maxSize &amp;&amp; len &gt; 0) {
                // Remove the least recently used
                var leastUsedEntry = list.head;
                list.remove(leastUsedEntry);
                delete map[leastUsedEntry.key];
            }
            var entry = list.insert(value);
            entry.key = key;
            map[key] = entry;
        }
    };
    /**
     * @param  {string} key
     * @return {}
     */
    LRUProto.get = function (key) {
        var entry = this._map[key];
        var list = this._list;
        if (entry != null) {
            // Put the latest used entry in the tail
            if (entry !== list.tail) {
                list.remove(entry);
                list.insertEntry(entry);
            }
            return entry.value;
        }
    };
    /**
     * Clear the cache
     */
    LRUProto.clear = function () {
        this._list.clear();
        this._map = {};
    };
    return LRU;
});
define(&apos;zrender/graphic/helper/poly&apos;, [&apos;require&apos;, &apos;./smoothSpline&apos;, &apos;./smoothBezier&apos;], function (require) {
    var smoothSpline = require(&apos;./smoothSpline&apos;);
    var smoothBezier = require(&apos;./smoothBezier&apos;);
    return {
        buildPath: function (ctx, shape, closePath) {
            var points = shape.points;
            var smooth = shape.smooth;
            if (points &amp;&amp; points.length &gt;= 2) {
                if (smooth &amp;&amp; smooth !== &apos;spline&apos;) {
                    var controlPoints = smoothBezier(points, smooth, closePath, shape.smoothConstraint);
                    ctx.moveTo(points[0][0], points[0][1]);
                    var len = points.length;
                    for (var i = 0; i &lt; (closePath ? len : len - 1); i++) {
                        var cp1 = controlPoints[i * 2];
                        var cp2 = controlPoints[i * 2 + 1];
                        var p = points[(i + 1) % len];
                        ctx.bezierCurveTo(cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]);
                    }
                } else {
                    if (smooth === &apos;spline&apos;) {
                        points = smoothSpline(points, closePath);
                    }
                    ctx.moveTo(points[0][0], points[0][1]);
                    for (var i = 1, l = points.length; i &lt; l; i++) {
                        ctx.lineTo(points[i][0], points[i][1]);
                    }
                }
                closePath &amp;&amp; ctx.closePath();
            }
        }
    };
});
define(&apos;zrender/graphic/helper/smoothSpline&apos;, [&apos;require&apos;, &apos;../../core/vector&apos;], function (require) {
    var vec2 = require(&apos;../../core/vector&apos;);
    /**
     * @inner
     */
    function interpolate(p0, p1, p2, p3, t, t2, t3) {
        var v0 = (p2 - p0) * 0.5;
        var v1 = (p3 - p1) * 0.5;
        return (2 * (p1 - p2) + v0 + v1) * t3 + (-3 * (p1 - p2) - 2 * v0 - v1) * t2 + v0 * t + p1;
    }
    /**
     * @alias module:zrender/shape/util/smoothSpline
     * @param {Array} points &#x7EBF;&#x6BB5;&#x9876;&#x70B9;&#x6570;&#x7EC4;
     * @param {boolean} isLoop
     * @return {Array}
     */
    return function (points, isLoop) {
        var len = points.length;
        var ret = [];
        var distance = 0;
        for (var i = 1; i &lt; len; i++) {
            distance += vec2.distance(points[i - 1], points[i]);
        }
        var segs = distance / 2;
        segs = segs &lt; len ? len : segs;
        for (var i = 0; i &lt; segs; i++) {
            var pos = i / (segs - 1) * (isLoop ? len : len - 1);
            var idx = Math.floor(pos);
            var w = pos - idx;
            var p0;
            var p1 = points[idx % len];
            var p2;
            var p3;
            if (!isLoop) {
                p0 = points[idx === 0 ? idx : idx - 1];
                p2 = points[idx &gt; len - 2 ? len - 1 : idx + 1];
                p3 = points[idx &gt; len - 3 ? len - 1 : idx + 2];
            } else {
                p0 = points[(idx - 1 + len) % len];
                p2 = points[(idx + 1) % len];
                p3 = points[(idx + 2) % len];
            }
            var w2 = w * w;
            var w3 = w * w2;
            ret.push([
                interpolate(p0[0], p1[0], p2[0], p3[0], w, w2, w3),
                interpolate(p0[1], p1[1], p2[1], p3[1], w, w2, w3)
            ]);
        }
        return ret;
    };
});
define(&apos;zrender/graphic/helper/smoothBezier&apos;, [&apos;require&apos;, &apos;../../core/vector&apos;], function (require) {
    var vec2 = require(&apos;../../core/vector&apos;);
    var v2Min = vec2.min;
    var v2Max = vec2.max;
    var v2Scale = vec2.scale;
    var v2Distance = vec2.distance;
    var v2Add = vec2.add;
    /**
     * &#x8D1D;&#x585E;&#x5C14;&#x5E73;&#x6ED1;&#x66F2;&#x7EBF;
     * @alias module:zrender/shape/util/smoothBezier
     * @param {Array} points &#x7EBF;&#x6BB5;&#x9876;&#x70B9;&#x6570;&#x7EC4;
     * @param {number} smooth &#x5E73;&#x6ED1;&#x7B49;&#x7EA7;, 0-1
     * @param {boolean} isLoop
     * @param {Array} constraint &#x5C06;&#x8BA1;&#x7B97;&#x51FA;&#x6765;&#x7684;&#x63A7;&#x5236;&#x70B9;&#x7EA6;&#x675F;&#x5728;&#x4E00;&#x4E2A;&#x5305;&#x56F4;&#x76D2;&#x5185;
     *                           &#x6BD4;&#x5982; [[0, 0], [100, 100]], &#x8FD9;&#x4E2A;&#x5305;&#x56F4;&#x76D2;&#x4F1A;&#x4E0E;
     *                           &#x6574;&#x4E2A;&#x6298;&#x7EBF;&#x7684;&#x5305;&#x56F4;&#x76D2;&#x505A;&#x4E00;&#x4E2A;&#x5E76;&#x96C6;&#x7528;&#x6765;&#x7EA6;&#x675F;&#x63A7;&#x5236;&#x70B9;&#x3002;
     * @param {Array} &#x8BA1;&#x7B97;&#x51FA;&#x6765;&#x7684;&#x63A7;&#x5236;&#x70B9;&#x6570;&#x7EC4;
     */
    return function (points, smooth, isLoop, constraint) {
        var cps = [];
        var v = [];
        var v1 = [];
        var v2 = [];
        var prevPoint;
        var nextPoint;
        var min, max;
        if (constraint) {
            min = [
                Infinity,
                Infinity
            ];
            max = [
                -Infinity,
                -Infinity
            ];
            for (var i = 0, len = points.length; i &lt; len; i++) {
                v2Min(min, min, points[i]);
                v2Max(max, max, points[i]);
            }
            // &#x4E0E;&#x6307;&#x5B9A;&#x7684;&#x5305;&#x56F4;&#x76D2;&#x505A;&#x5E76;&#x96C6;
            v2Min(min, min, constraint[0]);
            v2Max(max, max, constraint[1]);
        }
        for (var i = 0, len = points.length; i &lt; len; i++) {
            var point = points[i];
            if (isLoop) {
                prevPoint = points[i ? i - 1 : len - 1];
                nextPoint = points[(i + 1) % len];
            } else {
                if (i === 0 || i === len - 1) {
                    cps.push(vec2.clone(points[i]));
                    continue;
                } else {
                    prevPoint = points[i - 1];
                    nextPoint = points[i + 1];
                }
            }
            vec2.sub(v, nextPoint, prevPoint);
            // use degree to scale the handle length
            v2Scale(v, v, smooth);
            var d0 = v2Distance(point, prevPoint);
            var d1 = v2Distance(point, nextPoint);
            var sum = d0 + d1;
            if (sum !== 0) {
                d0 /= sum;
                d1 /= sum;
            }
            v2Scale(v1, v, -d0);
            v2Scale(v2, v, d1);
            var cp0 = v2Add([], point, v1);
            var cp1 = v2Add([], point, v2);
            if (constraint) {
                v2Max(cp0, cp0, min);
                v2Min(cp0, cp0, max);
                v2Max(cp1, cp1, min);
                v2Min(cp1, cp1, max);
            }
            cps.push(cp0);
            cps.push(cp1);
        }
        if (isLoop) {
            cps.push(cps.shift());
        }
        return cps;
    };
});
define(&apos;zrender/graphic/helper/roundRect&apos;, [&apos;require&apos;], function (require) {
    return {
        buildPath: function (ctx, shape) {
            var x = shape.x;
            var y = shape.y;
            var width = shape.width;
            var height = shape.height;
            var r = shape.r;
            var r1;
            var r2;
            var r3;
            var r4;
            // Convert width and height to positive for better borderRadius
            if (width &lt; 0) {
                x = x + width;
                width = -width;
            }
            if (height &lt; 0) {
                y = y + height;
                height = -height;
            }
            if (typeof r === &apos;number&apos;) {
                r1 = r2 = r3 = r4 = r;
            } else if (r instanceof Array) {
                if (r.length === 1) {
                    r1 = r2 = r3 = r4 = r[0];
                } else if (r.length === 2) {
                    r1 = r3 = r[0];
                    r2 = r4 = r[1];
                } else if (r.length === 3) {
                    r1 = r[0];
                    r2 = r4 = r[1];
                    r3 = r[2];
                } else {
                    r1 = r[0];
                    r2 = r[1];
                    r3 = r[2];
                    r4 = r[3];
                }
            } else {
                r1 = r2 = r3 = r4 = 0;
            }
            var total;
            if (r1 + r2 &gt; width) {
                total = r1 + r2;
                r1 *= width / total;
                r2 *= width / total;
            }
            if (r3 + r4 &gt; width) {
                total = r3 + r4;
                r3 *= width / total;
                r4 *= width / total;
            }
            if (r2 + r3 &gt; height) {
                total = r2 + r3;
                r2 *= height / total;
                r3 *= height / total;
            }
            if (r1 + r4 &gt; height) {
                total = r1 + r4;
                r1 *= height / total;
                r4 *= height / total;
            }
            ctx.moveTo(x + r1, y);
            ctx.lineTo(x + width - r2, y);
            r2 !== 0 &amp;&amp; ctx.quadraticCurveTo(x + width, y, x + width, y + r2);
            ctx.lineTo(x + width, y + height - r3);
            r3 !== 0 &amp;&amp; ctx.quadraticCurveTo(x + width, y + height, x + width - r3, y + height);
            ctx.lineTo(x + r4, y + height);
            r4 !== 0 &amp;&amp; ctx.quadraticCurveTo(x, y + height, x, y + height - r4);
            ctx.lineTo(x, y + r1);
            r1 !== 0 &amp;&amp; ctx.quadraticCurveTo(x, y, x + r1, y);
        }
    };
});
define(&apos;zrender/Painter&apos;, [&apos;require&apos;, &apos;./config&apos;, &apos;./core/util&apos;, &apos;./core/log&apos;, &apos;./core/BoundingRect&apos;, &apos;./core/timsort&apos;, &apos;./Layer&apos;, &apos;./animation/requestAnimationFrame&apos;, &apos;./graphic/Image&apos;], function (require) {
    &apos;use strict&apos;;
    var config = require(&apos;./config&apos;);
    var util = require(&apos;./core/util&apos;);
    var log = require(&apos;./core/log&apos;);
    var BoundingRect = require(&apos;./core/BoundingRect&apos;);
    var timsort = require(&apos;./core/timsort&apos;);
    var Layer = require(&apos;./Layer&apos;);
    var requestAnimationFrame = require(&apos;./animation/requestAnimationFrame&apos;);
    // PENDIGN
    // Layer exceeds MAX_PROGRESSIVE_LAYER_NUMBER may have some problem when flush directly second time.
    //
    // Maximum progressive layer. When exceeding this number. All elements will be drawed in the last layer.
    var MAX_PROGRESSIVE_LAYER_NUMBER = 5;
    function parseInt10(val) {
        return parseInt(val, 10);
    }
    function isLayerValid(layer) {
        if (!layer) {
            return false;
        }
        if (layer.isBuildin) {
            return true;
        }
        if (typeof layer.resize !== &apos;function&apos; || typeof layer.refresh !== &apos;function&apos;) {
            return false;
        }
        return true;
    }
    function preProcessLayer(layer) {
        layer.__unusedCount++;
    }
    function postProcessLayer(layer) {
        if (layer.__unusedCount == 1) {
            layer.clear();
        }
    }
    var tmpRect = new BoundingRect(0, 0, 0, 0);
    var viewRect = new BoundingRect(0, 0, 0, 0);
    function isDisplayableCulled(el, width, height) {
        tmpRect.copy(el.getBoundingRect());
        if (el.transform) {
            tmpRect.applyTransform(el.transform);
        }
        viewRect.width = width;
        viewRect.height = height;
        return !tmpRect.intersect(viewRect);
    }
    function isClipPathChanged(clipPaths, prevClipPaths) {
        if (clipPaths == prevClipPaths) {
            // Can both be null or undefined
            return false;
        }
        if (!clipPaths || !prevClipPaths || clipPaths.length !== prevClipPaths.length) {
            return true;
        }
        for (var i = 0; i &lt; clipPaths.length; i++) {
            if (clipPaths[i] !== prevClipPaths[i]) {
                return true;
            }
        }
    }
    function doClip(clipPaths, ctx) {
        for (var i = 0; i &lt; clipPaths.length; i++) {
            var clipPath = clipPaths[i];
            var m;
            if (clipPath.transform) {
                m = clipPath.transform;
                ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
            }
            var path = clipPath.path;
            path.beginPath(ctx);
            clipPath.buildPath(path, clipPath.shape);
            ctx.clip();
            // Transform back
            if (clipPath.transform) {
                m = clipPath.invTransform;
                ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
            }
        }
    }
    function createRoot(width, height) {
        var domRoot = document.createElement(&apos;div&apos;);
        var domRootStyle = domRoot.style;
        // domRoot.onselectstart = returnFalse; // &#x907F;&#x514D;&#x9875;&#x9762;&#x9009;&#x4E2D;&#x7684;&#x5C34;&#x5C2C;
        domRootStyle.position = &apos;relative&apos;;
        domRootStyle.overflow = &apos;hidden&apos;;
        domRootStyle.width = width + &apos;px&apos;;
        domRootStyle.height = height + &apos;px&apos;;
        return domRoot;
    }
    /**
     * @alias module:zrender/Painter
     * @constructor
     * @param {HTMLElement} root &#x7ED8;&#x56FE;&#x5BB9;&#x5668;
     * @param {module:zrender/Storage} storage
     * @param {Ojbect} opts
     */
    var Painter = function (root, storage, opts) {
        // In node environment using node-canvas
        var singleCanvas = !root.nodeName || root.nodeName.toUpperCase() === &apos;CANVAS&apos;;
        opts = opts || {};
        /**
         * @type {number}
         */
        this.dpr = opts.devicePixelRatio || config.devicePixelRatio;
        /**
         * @type {boolean}
         * @private
         */
        this._singleCanvas = singleCanvas;
        /**
         * &#x7ED8;&#x56FE;&#x5BB9;&#x5668;
         * @type {HTMLElement}
         */
        this.root = root;
        var rootStyle = root.style;
        if (rootStyle) {
            rootStyle[&apos;-webkit-tap-highlight-color&apos;] = &apos;transparent&apos;;
            rootStyle[&apos;-webkit-user-select&apos;] = rootStyle[&apos;user-select&apos;] = rootStyle[&apos;-webkit-touch-callout&apos;] = &apos;none&apos;;
            root.innerHTML = &apos;&apos;;
        }
        /**
         * @type {module:zrender/Storage}
         */
        this.storage = storage;
        /**
         * @type {Array.<number>}
         * @private
         */
        var zlevelList = this._zlevelList = [];
        /**
         * @type {Object.<string, module:zrender="" layer="">}
         * @private
         */
        var layers = this._layers = {};
        /**
         * @type {Object.<string, object="">}
         * @type {private}
         */
        this._layerConfig = {};
        if (!singleCanvas) {
            this._width = this._getWidth();
            this._height = this._getHeight();
            var domRoot = this._domRoot = createRoot(this._width, this._height);
            root.appendChild(domRoot);
        } else {
            // Use canvas width and height directly
            var width = root.width;
            var height = root.height;
            this._width = width;
            this._height = height;
            // Create layer if only one given canvas
            // Device pixel ratio is fixed to 1 because given canvas has its specified width and height
            var mainLayer = new Layer(root, this, 1);
            mainLayer.initContext();
            // FIXME Use canvas width and height
            // mainLayer.resize(width, height);
            layers[0] = mainLayer;
            zlevelList.push(0);
        }
        this.pathToImage = this._createPathToImage();
        // Layers for progressive rendering
        this._progressiveLayers = [];
        /**
         * @type {module:zrender/Layer}
         * @private
         */
        this._hoverlayer;
        this._hoverElements = [];
    };
    Painter.prototype = {
        constructor: Painter,
        isSingleCanvas: function () {
            return this._singleCanvas;
        },
        getViewportRoot: function () {
            return this._singleCanvas ? this._layers[0].dom : this._domRoot;
        },
        refresh: function (paintAll) {
            var list = this.storage.getDisplayList(true);
            var zlevelList = this._zlevelList;
            this._paintList(list, paintAll);
            // Paint custum layers
            for (var i = 0; i &lt; zlevelList.length; i++) {
                var z = zlevelList[i];
                var layer = this._layers[z];
                if (!layer.isBuildin &amp;&amp; layer.refresh) {
                    layer.refresh();
                }
            }
            this.refreshHover();
            if (this._progressiveLayers.length) {
                this._startProgessive();
            }
            return this;
        },
        addHover: function (el, hoverStyle) {
            if (el.__hoverMir) {
                return;
            }
            var elMirror = new el.constructor({
                    style: el.style,
                    shape: el.shape
                });
            elMirror.__from = el;
            el.__hoverMir = elMirror;
            elMirror.setStyle(hoverStyle);
            this._hoverElements.push(elMirror);
        },
        removeHover: function (el) {
            var elMirror = el.__hoverMir;
            var hoverElements = this._hoverElements;
            var idx = util.indexOf(hoverElements, elMirror);
            if (idx &gt;= 0) {
                hoverElements.splice(idx, 1);
            }
            el.__hoverMir = null;
        },
        clearHover: function (el) {
            var hoverElements = this._hoverElements;
            for (var i = 0; i &lt; hoverElements.length; i++) {
                var from = hoverElements[i].__from;
                if (from) {
                    from.__hoverMir = null;
                }
            }
            hoverElements.length = 0;
        },
        refreshHover: function () {
            var hoverElements = this._hoverElements;
            var len = hoverElements.length;
            var hoverLayer = this._hoverlayer;
            hoverLayer &amp;&amp; hoverLayer.clear();
            if (!len) {
                return;
            }
            timsort(hoverElements, this.storage.displayableSortFunc);
            // Use a extream large zlevel
            // FIXME?
            if (!hoverLayer) {
                hoverLayer = this._hoverlayer = this.getLayer(100000);
            }
            var scope = {};
            hoverLayer.ctx.save();
            for (var i = 0; i &lt; len;) {
                var el = hoverElements[i];
                var originalEl = el.__from;
                // Original el is removed
                // PENDING
                if (!(originalEl &amp;&amp; originalEl.__zr)) {
                    hoverElements.splice(i, 1);
                    originalEl.__hoverMir = null;
                    len--;
                    continue;
                }
                i++;
                // Use transform
                // FIXME style and shape ?
                if (!originalEl.invisible) {
                    el.transform = originalEl.transform;
                    el.invTransform = originalEl.invTransform;
                    el.__clipPaths = originalEl.__clipPaths;
                    // el.
                    this._doPaintEl(el, hoverLayer, true, scope);
                }
            }
            hoverLayer.ctx.restore();
        },
        _startProgessive: function () {
            var self = this;
            if (!self._furtherProgressive) {
                return;
            }
            // Use a token to stop progress steps triggered by
            // previous zr.refresh calling.
            var token = self._progressiveToken = +new Date();
            self._progress++;
            requestAnimationFrame(step);
            function step() {
                // In case refreshed or disposed
                if (token === self._progressiveToken &amp;&amp; self.storage) {
                    self._doPaintList(self.storage.getDisplayList());
                    if (self._furtherProgressive) {
                        self._progress++;
                        requestAnimationFrame(step);
                    } else {
                        self._progressiveToken = -1;
                    }
                }
            }
        },
        _clearProgressive: function () {
            this._progressiveToken = -1;
            this._progress = 0;
            util.each(this._progressiveLayers, function (layer) {
                layer.__dirty &amp;&amp; layer.clear();
            });
        },
        _paintList: function (list, paintAll) {
            if (paintAll == null) {
                paintAll = false;
            }
            this._updateLayerStatus(list);
            this._clearProgressive();
            this.eachBuildinLayer(preProcessLayer);
            this._doPaintList(list, paintAll);
            this.eachBuildinLayer(postProcessLayer);
        },
        _doPaintList: function (list, paintAll) {
            var currentLayer;
            var currentZLevel;
            var ctx;
            // var invTransform = [];
            var scope;
            var progressiveLayerIdx = 0;
            var currentProgressiveLayer;
            var width = this._width;
            var height = this._height;
            var layerProgress;
            var frame = this._progress;
            function flushProgressiveLayer(layer) {
                ctx.save();
                ctx.globalAlpha = 1;
                ctx.shadowBlur = 0;
                // Avoid layer don&apos;t clear in next progressive frame
                currentLayer.__dirty = true;
                ctx.drawImage(layer.dom, 0, 0, width, height);
                ctx.restore();
                currentLayer.ctx.restore();
            }
            for (var i = 0, l = list.length; i &lt; l; i++) {
                var el = list[i];
                var elZLevel = this._singleCanvas ? 0 : el.zlevel;
                var elFrame = el.__frame;
                // Flush at current context
                // PENDING
                if (elFrame &lt; 0 &amp;&amp; currentProgressiveLayer) {
                    flushProgressiveLayer(currentProgressiveLayer);
                    currentProgressiveLayer = null;
                }
                // Change draw layer
                if (currentZLevel !== elZLevel) {
                    if (ctx) {
                        ctx.restore();
                    }
                    // Reset scope
                    scope = {};
                    // Only 0 zlevel if only has one canvas
                    currentZLevel = elZLevel;
                    currentLayer = this.getLayer(currentZLevel);
                    if (!currentLayer.isBuildin) {
                        log(&apos;ZLevel &apos; + currentZLevel + &apos; has been used by unkown layer &apos; + currentLayer.id);
                    }
                    ctx = currentLayer.ctx;
                    ctx.save();
                    // Reset the count
                    currentLayer.__unusedCount = 0;
                    if (currentLayer.__dirty || paintAll) {
                        currentLayer.clear();
                    }
                }
                if (!(currentLayer.__dirty || paintAll)) {
                    continue;
                }
                if (elFrame &gt;= 0) {
                    // Progressive layer changed
                    if (!currentProgressiveLayer) {
                        currentProgressiveLayer = this._progressiveLayers[Math.min(progressiveLayerIdx++, MAX_PROGRESSIVE_LAYER_NUMBER - 1)];
                        currentProgressiveLayer.ctx.save();
                        currentProgressiveLayer.renderScope = {};
                        if (currentProgressiveLayer &amp;&amp; currentProgressiveLayer.__progress &gt; currentProgressiveLayer.__maxProgress) {
                            // flushProgressiveLayer(currentProgressiveLayer);
                            // Quick jump all progressive elements
                            // All progressive element are not dirty, jump over and flush directly
                            i = currentProgressiveLayer.__nextIdxNotProg - 1;
                            // currentProgressiveLayer = null;
                            continue;
                        }
                        layerProgress = currentProgressiveLayer.__progress;
                        if (!currentProgressiveLayer.__dirty) {
                            // Keep rendering
                            frame = layerProgress;
                        }
                        currentProgressiveLayer.__progress = frame + 1;
                    }
                    if (elFrame === frame) {
                        this._doPaintEl(el, currentProgressiveLayer, true, currentProgressiveLayer.renderScope);
                    }
                } else {
                    this._doPaintEl(el, currentLayer, paintAll, scope);
                }
                el.__dirty = false;
            }
            if (currentProgressiveLayer) {
                flushProgressiveLayer(currentProgressiveLayer);
            }
            // Restore the lastLayer ctx
            ctx &amp;&amp; ctx.restore();
            // If still has clipping state
            // if (scope.prevElClipPaths) {
            //     ctx.restore();
            // }
            this._furtherProgressive = false;
            util.each(this._progressiveLayers, function (layer) {
                if (layer.__maxProgress &gt;= layer.__progress) {
                    this._furtherProgressive = true;
                }
            }, this);
        },
        _doPaintEl: function (el, currentLayer, forcePaint, scope) {
            var ctx = currentLayer.ctx;
            if ((currentLayer.__dirty || forcePaint) &amp;&amp; !el.invisible &amp;&amp; el.style.opacity !== 0 &amp;&amp; el.scale[0] &amp;&amp; el.scale[1] &amp;&amp; !(el.culling &amp;&amp; isDisplayableCulled(el, this._width, this._height))) {
                var clipPaths = el.__clipPaths;
                // Optimize when clipping on group with several elements
                if (scope.prevClipLayer !== currentLayer || isClipPathChanged(clipPaths, scope.prevElClipPaths)) {
                    // If has previous clipping state, restore from it
                    if (scope.prevElClipPaths) {
                        scope.prevClipLayer.ctx.restore();
                        scope.prevClipLayer = scope.prevElClipPaths = null;
                        // Reset prevEl since context has been restored
                        scope.prevEl = null;
                    }
                    // New clipping state
                    if (clipPaths) {
                        ctx.save();
                        doClip(clipPaths, ctx);
                        scope.prevClipLayer = currentLayer;
                        scope.prevElClipPaths = clipPaths;
                    }
                }
                el.beforeBrush &amp;&amp; el.beforeBrush(ctx);
                el.brush(ctx, scope.prevEl || null);
                scope.prevEl = el;
                el.afterBrush &amp;&amp; el.afterBrush(ctx);
            }
        },
        getLayer: function (zlevel) {
            if (this._singleCanvas) {
                return this._layers[0];
            }
            var layer = this._layers[zlevel];
            if (!layer) {
                // Create a new layer
                layer = new Layer(&apos;zr_&apos; + zlevel, this, this.dpr);
                layer.isBuildin = true;
                if (this._layerConfig[zlevel]) {
                    util.merge(layer, this._layerConfig[zlevel], true);
                }
                this.insertLayer(zlevel, layer);
                // Context is created after dom inserted to document
                // Or excanvas will get 0px clientWidth and clientHeight
                layer.initContext();
            }
            return layer;
        },
        insertLayer: function (zlevel, layer) {
            var layersMap = this._layers;
            var zlevelList = this._zlevelList;
            var len = zlevelList.length;
            var prevLayer = null;
            var i = -1;
            var domRoot = this._domRoot;
            if (layersMap[zlevel]) {
                log(&apos;ZLevel &apos; + zlevel + &apos; has been used already&apos;);
                return;
            }
            // Check if is a valid layer
            if (!isLayerValid(layer)) {
                log(&apos;Layer of zlevel &apos; + zlevel + &apos; is not valid&apos;);
                return;
            }
            if (len &gt; 0 &amp;&amp; zlevel &gt; zlevelList[0]) {
                for (i = 0; i &lt; len - 1; i++) {
                    if (zlevelList[i] &lt; zlevel &amp;&amp; zlevelList[i + 1] &gt; zlevel) {
                        break;
                    }
                }
                prevLayer = layersMap[zlevelList[i]];
            }
            zlevelList.splice(i + 1, 0, zlevel);
            if (prevLayer) {
                var prevDom = prevLayer.dom;
                if (prevDom.nextSibling) {
                    domRoot.insertBefore(layer.dom, prevDom.nextSibling);
                } else {
                    domRoot.appendChild(layer.dom);
                }
            } else {
                if (domRoot.firstChild) {
                    domRoot.insertBefore(layer.dom, domRoot.firstChild);
                } else {
                    domRoot.appendChild(layer.dom);
                }
            }
            layersMap[zlevel] = layer;
        },
        eachLayer: function (cb, context) {
            var zlevelList = this._zlevelList;
            var z;
            var i;
            for (i = 0; i &lt; zlevelList.length; i++) {
                z = zlevelList[i];
                cb.call(context, this._layers[z], z);
            }
        },
        eachBuildinLayer: function (cb, context) {
            var zlevelList = this._zlevelList;
            var layer;
            var z;
            var i;
            for (i = 0; i &lt; zlevelList.length; i++) {
                z = zlevelList[i];
                layer = this._layers[z];
                if (layer.isBuildin) {
                    cb.call(context, layer, z);
                }
            }
        },
        eachOtherLayer: function (cb, context) {
            var zlevelList = this._zlevelList;
            var layer;
            var z;
            var i;
            for (i = 0; i &lt; zlevelList.length; i++) {
                z = zlevelList[i];
                layer = this._layers[z];
                if (!layer.isBuildin) {
                    cb.call(context, layer, z);
                }
            }
        },
        getLayers: function () {
            return this._layers;
        },
        _updateLayerStatus: function (list) {
            var layers = this._layers;
            var progressiveLayers = this._progressiveLayers;
            var elCountsLastFrame = {};
            var progressiveElCountsLastFrame = {};
            this.eachBuildinLayer(function (layer, z) {
                elCountsLastFrame[z] = layer.elCount;
                layer.elCount = 0;
                layer.__dirty = false;
            });
            util.each(progressiveLayers, function (layer, idx) {
                progressiveElCountsLastFrame[idx] = layer.elCount;
                layer.elCount = 0;
                layer.__dirty = false;
            });
            var progressiveLayerCount = 0;
            var currentProgressiveLayer;
            var lastProgressiveKey;
            var frameCount = 0;
            for (var i = 0, l = list.length; i &lt; l; i++) {
                var el = list[i];
                var zlevel = this._singleCanvas ? 0 : el.zlevel;
                var layer = layers[zlevel];
                var elProgress = el.progressive;
                if (layer) {
                    layer.elCount++;
                    layer.__dirty = layer.__dirty || el.__dirty;
                }
                /////// Update progressive
                if (elProgress &gt;= 0) {
                    // Fix wrong progressive sequence problem.
                    if (lastProgressiveKey !== elProgress) {
                        lastProgressiveKey = elProgress;
                        frameCount++;
                    }
                    var elFrame = el.__frame = frameCount - 1;
                    if (!currentProgressiveLayer) {
                        var idx = Math.min(progressiveLayerCount, MAX_PROGRESSIVE_LAYER_NUMBER - 1);
                        currentProgressiveLayer = progressiveLayers[idx];
                        if (!currentProgressiveLayer) {
                            currentProgressiveLayer = progressiveLayers[idx] = new Layer(&apos;progressive&apos;, this, this.dpr);
                            currentProgressiveLayer.initContext();
                        }
                        currentProgressiveLayer.__maxProgress = 0;
                    }
                    currentProgressiveLayer.__dirty = currentProgressiveLayer.__dirty || el.__dirty;
                    currentProgressiveLayer.elCount++;
                    currentProgressiveLayer.__maxProgress = Math.max(currentProgressiveLayer.__maxProgress, elFrame);
                    if (currentProgressiveLayer.__maxProgress &gt;= currentProgressiveLayer.__progress) {
                        // Should keep rendering this  layer because progressive rendering is not finished yet
                        layer.__dirty = true;
                    }
                } else {
                    el.__frame = -1;
                    if (currentProgressiveLayer) {
                        currentProgressiveLayer.__nextIdxNotProg = i;
                        progressiveLayerCount++;
                        currentProgressiveLayer = null;
                    }
                }
            }
            if (currentProgressiveLayer) {
                progressiveLayerCount++;
                currentProgressiveLayer.__nextIdxNotProg = i;
            }
            // &#x5C42;&#x4E2D;&#x7684;&#x5143;&#x7D20;&#x6570;&#x91CF;&#x6709;&#x53D1;&#x751F;&#x53D8;&#x5316;
            this.eachBuildinLayer(function (layer, z) {
                if (elCountsLastFrame[z] !== layer.elCount) {
                    layer.__dirty = true;
                }
            });
            progressiveLayers.length = Math.min(progressiveLayerCount, MAX_PROGRESSIVE_LAYER_NUMBER);
            util.each(progressiveLayers, function (layer, idx) {
                if (progressiveElCountsLastFrame[idx] !== layer.elCount) {
                    el.__dirty = true;
                }
                if (layer.__dirty) {
                    layer.__progress = 0;
                }
            });
        },
        clear: function () {
            this.eachBuildinLayer(this._clearLayer);
            return this;
        },
        _clearLayer: function (layer) {
            layer.clear();
        },
        configLayer: function (zlevel, config) {
            if (config) {
                var layerConfig = this._layerConfig;
                if (!layerConfig[zlevel]) {
                    layerConfig[zlevel] = config;
                } else {
                    util.merge(layerConfig[zlevel], config, true);
                }
                var layer = this._layers[zlevel];
                if (layer) {
                    util.merge(layer, layerConfig[zlevel], true);
                }
            }
        },
        delLayer: function (zlevel) {
            var layers = this._layers;
            var zlevelList = this._zlevelList;
            var layer = layers[zlevel];
            if (!layer) {
                return;
            }
            layer.dom.parentNode.removeChild(layer.dom);
            delete layers[zlevel];
            zlevelList.splice(util.indexOf(zlevelList, zlevel), 1);
        },
        resize: function (width, height) {
            var domRoot = this._domRoot;
            // FIXME Why ?
            domRoot.style.display = &apos;none&apos;;
            width = width || this._getWidth();
            height = height || this._getHeight();
            domRoot.style.display = &apos;&apos;;
            // &#x4F18;&#x5316;&#x6CA1;&#x6709;&#x5B9E;&#x9645;&#x6539;&#x53D8;&#x7684;resize
            if (this._width != width || height != this._height) {
                domRoot.style.width = width + &apos;px&apos;;
                domRoot.style.height = height + &apos;px&apos;;
                for (var id in this._layers) {
                    this._layers[id].resize(width, height);
                }
                this.refresh(true);
            }
            this._width = width;
            this._height = height;
            return this;
        },
        clearLayer: function (zlevel) {
            var layer = this._layers[zlevel];
            if (layer) {
                layer.clear();
            }
        },
        dispose: function () {
            this.root.innerHTML = &apos;&apos;;
            this.root = this.storage = this._domRoot = this._layers = null;
        },
        getRenderedCanvas: function (opts) {
            opts = opts || {};
            if (this._singleCanvas) {
                return this._layers[0].dom;
            }
            var imageLayer = new Layer(&apos;image&apos;, this, opts.pixelRatio || this.dpr);
            imageLayer.initContext();
            imageLayer.clearColor = opts.backgroundColor;
            imageLayer.clear();
            var displayList = this.storage.getDisplayList(true);
            var scope = {};
            for (var i = 0; i &lt; displayList.length; i++) {
                var el = displayList[i];
                this._doPaintEl(el, imageLayer, true, scope);
            }
            return imageLayer.dom;
        },
        getWidth: function () {
            return this._width;
        },
        getHeight: function () {
            return this._height;
        },
        _getWidth: function () {
            var root = this.root;
            var stl = document.defaultView.getComputedStyle(root);
            // FIXME Better way to get the width and height when element has not been append to the document
            return (root.clientWidth || parseInt10(stl.width) || parseInt10(root.style.width)) - (parseInt10(stl.paddingLeft) || 0) - (parseInt10(stl.paddingRight) || 0) | 0;
        },
        _getHeight: function () {
            var root = this.root;
            var stl = document.defaultView.getComputedStyle(root);
            return (root.clientHeight || parseInt10(stl.height) || parseInt10(root.style.height)) - (parseInt10(stl.paddingTop) || 0) - (parseInt10(stl.paddingBottom) || 0) | 0;
        },
        _pathToImage: function (id, path, width, height, dpr) {
            var canvas = document.createElement(&apos;canvas&apos;);
            var ctx = canvas.getContext(&apos;2d&apos;);
            canvas.width = width * dpr;
            canvas.height = height * dpr;
            ctx.clearRect(0, 0, width * dpr, height * dpr);
            var pathTransform = {
                    position: path.position,
                    rotation: path.rotation,
                    scale: path.scale
                };
            path.position = [
                0,
                0,
                0
            ];
            path.rotation = 0;
            path.scale = [
                1,
                1
            ];
            if (path) {
                path.brush(ctx);
            }
            var ImageShape = require(&apos;./graphic/Image&apos;);
            var imgShape = new ImageShape({
                    id: id,
                    style: {
                        x: 0,
                        y: 0,
                        image: canvas
                    }
                });
            if (pathTransform.position != null) {
                imgShape.position = path.position = pathTransform.position;
            }
            if (pathTransform.rotation != null) {
                imgShape.rotation = path.rotation = pathTransform.rotation;
            }
            if (pathTransform.scale != null) {
                imgShape.scale = path.scale = pathTransform.scale;
            }
            return imgShape;
        },
        _createPathToImage: function () {
            var me = this;
            return function (id, e, width, height) {
                return me._pathToImage(id, e, width, height, me.dpr);
            };
        }
    };
    return Painter;
});
define(&apos;zrender/Handler&apos;, [&apos;require&apos;, &apos;./core/util&apos;, &apos;./mixin/Draggable&apos;, &apos;./mixin/Eventful&apos;], function (require) {
    &apos;use strict&apos;;
    var util = require(&apos;./core/util&apos;);
    var Draggable = require(&apos;./mixin/Draggable&apos;);
    var Eventful = require(&apos;./mixin/Eventful&apos;);
    function makeEventPacket(eveType, target, event) {
        return {
            type: eveType,
            event: event,
            target: target,
            cancelBubble: false,
            offsetX: event.zrX,
            offsetY: event.zrY,
            gestureEvent: event.gestureEvent,
            pinchX: event.pinchX,
            pinchY: event.pinchY,
            pinchScale: event.pinchScale,
            wheelDelta: event.zrDelta
        };
    }
    function EmptyProxy() {
    }
    EmptyProxy.prototype.dispose = function () {
    };
    var handlerNames = [
            &apos;click&apos;,
            &apos;dblclick&apos;,
            &apos;mousewheel&apos;,
            &apos;mouseout&apos;,
            &apos;mouseup&apos;,
            &apos;mousedown&apos;,
            &apos;mousemove&apos;
        ];
    /**
     * @alias module:zrender/Handler
     * @constructor
     * @extends module:zrender/mixin/Eventful
     * @param {HTMLElement} root Main HTML element for painting.
     * @param {module:zrender/Storage} storage Storage instance.
     * @param {module:zrender/Painter} painter Painter instance.
     */
    var Handler = function (storage, painter, proxy) {
        Eventful.call(this);
        this.storage = storage;
        this.painter = painter;
        proxy = proxy || new EmptyProxy();
        /**
         * Proxy of event. can be Dom, WebGLSurface, etc.
         */
        this.proxy = proxy;
        // Attach handler
        proxy.handler = this;
        /**
         * @private
         * @type {boolean}
         */
        this._hovered;
        /**
         * @private
         * @type {Date}
         */
        this._lastTouchMoment;
        /**
         * @private
         * @type {number}
         */
        this._lastX;
        /**
         * @private
         * @type {number}
         */
        this._lastY;
        Draggable.call(this);
        util.each(handlerNames, function (name) {
            proxy.on &amp;&amp; proxy.on(name, this[name], this);
        }, this);
    };
    Handler.prototype = {
        constructor: Handler,
        mousemove: function (event) {
            var x = event.zrX;
            var y = event.zrY;
            var hovered = this.findHover(x, y, null);
            var lastHovered = this._hovered;
            var proxy = this.proxy;
            this._hovered = hovered;
            proxy.setCursor &amp;&amp; proxy.setCursor(hovered ? hovered.cursor : &apos;default&apos;);
            // Mouse out on previous hovered element
            if (lastHovered &amp;&amp; hovered !== lastHovered &amp;&amp; lastHovered.__zr) {
                this.dispatchToElement(lastHovered, &apos;mouseout&apos;, event);
            }
            // Mouse moving on one element
            this.dispatchToElement(hovered, &apos;mousemove&apos;, event);
            // Mouse over on a new element
            if (hovered &amp;&amp; hovered !== lastHovered) {
                this.dispatchToElement(hovered, &apos;mouseover&apos;, event);
            }
        },
        mouseout: function (event) {
            this.dispatchToElement(this._hovered, &apos;mouseout&apos;, event);
            this.trigger(&apos;globalout&apos;, { event: event });
        },
        resize: function (event) {
            this._hovered = null;
        },
        dispatch: function (eventName, eventArgs) {
            var handler = this[eventName];
            handler &amp;&amp; handler.call(this, eventArgs);
        },
        dispose: function () {
            this.proxy.dispose();
            this.storage = this.proxy = this.painter = null;
        },
        setCursorStyle: function (cursorStyle) {
            var proxy = this.proxy;
            proxy.setCursor &amp;&amp; proxy.setCursor(cursorStyle);
        },
        dispatchToElement: function (targetEl, eventName, event) {
            var eventHandler = &apos;on&apos; + eventName;
            var eventPacket = makeEventPacket(eventName, targetEl, event);
            var el = targetEl;
            while (el) {
                el[eventHandler] &amp;&amp; (eventPacket.cancelBubble = el[eventHandler].call(el, eventPacket));
                el.trigger(eventName, eventPacket);
                el = el.parent;
                if (eventPacket.cancelBubble) {
                    break;
                }
            }
            if (!eventPacket.cancelBubble) {
                // &#x5192;&#x6CE1;&#x5230;&#x9876;&#x7EA7; zrender &#x5BF9;&#x8C61;
                this.trigger(eventName, eventPacket);
                // &#x5206;&#x53D1;&#x4E8B;&#x4EF6;&#x5230;&#x7528;&#x6237;&#x81EA;&#x5B9A;&#x4E49;&#x5C42;
                // &#x7528;&#x6237;&#x6709;&#x53EF;&#x80FD;&#x5728;&#x5168;&#x5C40; click &#x4E8B;&#x4EF6;&#x4E2D; dispose&#xFF0C;&#x6240;&#x4EE5;&#x9700;&#x8981;&#x5224;&#x65AD;&#x4E0B; painter &#x662F;&#x5426;&#x5B58;&#x5728;
                this.painter &amp;&amp; this.painter.eachOtherLayer(function (layer) {
                    if (typeof layer[eventHandler] == &apos;function&apos;) {
                        layer[eventHandler].call(layer, eventPacket);
                    }
                    if (layer.trigger) {
                        layer.trigger(eventName, eventPacket);
                    }
                });
            }
        },
        findHover: function (x, y, exclude) {
            var list = this.storage.getDisplayList();
            for (var i = list.length - 1; i &gt;= 0; i--) {
                if (!list[i].silent &amp;&amp; list[i] !== exclude &amp;&amp; !list[i].ignore &amp;&amp; isHover(list[i], x, y)) {
                    return list[i];
                }
            }
        }
    };
    // Common handlers
    util.each([
        &apos;click&apos;,
        &apos;mousedown&apos;,
        &apos;mouseup&apos;,
        &apos;mousewheel&apos;,
        &apos;dblclick&apos;
    ], function (name) {
        Handler.prototype[name] = function (event) {
            // Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover
            var hovered = this.findHover(event.zrX, event.zrY, null);
            if (name === &apos;mousedown&apos;) {
                this._downel = hovered;
                // In case click triggered before mouseup
                this._upel = hovered;
            } else if (name === &apos;mosueup&apos;) {
                this._upel = hovered;
            } else if (name === &apos;click&apos;) {
                if (this._downel !== this._upel) {
                    return;
                }
            }
            this.dispatchToElement(hovered, name, event);
        };
    });
    function isHover(displayable, x, y) {
        if (displayable[displayable.rectHover ? &apos;rectContain&apos; : &apos;contain&apos;](x, y)) {
            var el = displayable;
            while (el) {
                // If ancestor is silent or clipped by ancestor
                if (el.silent || el.clipPath &amp;&amp; !el.clipPath.contain(x, y)) {
                    return false;
                }
                el = el.parent;
            }
            return true;
        }
        return false;
    }
    util.mixin(Handler, Eventful);
    util.mixin(Handler, Draggable);
    return Handler;
});
define(&apos;zrender/dom/HandlerProxy&apos;, [&apos;require&apos;, &apos;../core/event&apos;, &apos;../core/util&apos;, &apos;../mixin/Eventful&apos;, &apos;../core/env&apos;, &apos;../core/GestureMgr&apos;], function (require) {
    var eventTool = require(&apos;../core/event&apos;);
    var zrUtil = require(&apos;../core/util&apos;);
    var Eventful = require(&apos;../mixin/Eventful&apos;);
    var env = require(&apos;../core/env&apos;);
    var GestureMgr = require(&apos;../core/GestureMgr&apos;);
    var addEventListener = eventTool.addEventListener;
    var removeEventListener = eventTool.removeEventListener;
    var normalizeEvent = eventTool.normalizeEvent;
    var TOUCH_CLICK_DELAY = 300;
    var mouseHandlerNames = [
            &apos;click&apos;,
            &apos;dblclick&apos;,
            &apos;mousewheel&apos;,
            &apos;mouseout&apos;,
            &apos;mouseup&apos;,
            &apos;mousedown&apos;,
            &apos;mousemove&apos;
        ];
    var touchHandlerNames = [
            &apos;touchstart&apos;,
            &apos;touchend&apos;,
            &apos;touchmove&apos;
        ];
    function eventNameFix(name) {
        return name === &apos;mousewheel&apos; &amp;&amp; env.browser.firefox ? &apos;DOMMouseScroll&apos; : name;
    }
    function processGesture(proxy, event, stage) {
        var gestureMgr = proxy._gestureMgr;
        stage === &apos;start&apos; &amp;&amp; gestureMgr.clear();
        var gestureInfo = gestureMgr.recognize(event, proxy.handler.findHover(event.zrX, event.zrY, null), proxy.dom);
        stage === &apos;end&apos; &amp;&amp; gestureMgr.clear();
        if (gestureInfo) {
            // eventTool.stop(event);
            var type = gestureInfo.type;
            event.gestureEvent = type;
            proxy.handler.dispatchToElement(gestureInfo.target, type, gestureInfo.event);
        }
    }
    /**
     * Prevent mouse event from being dispatched after Touch Events action
     * @see <https: github.com="" deltakosh="" handjs="" blob="" master="" src="" hand.base.js="">
     * 1. Mobile browsers dispatch mouse events 300ms after touchend.
     * 2. Chrome for Android dispatch mousedown for long-touch about 650ms
     * Result: Blocking Mouse Events for 700ms.
     */
    function setTouchTimer(instance) {
        instance._touching = true;
        clearTimeout(instance._touchTimer);
        instance._touchTimer = setTimeout(function () {
            instance._touching = false;
        }, 700);
    }
    function useTouchEvent() {
        return env.touchEventsSupported;
    }
    var domHandlers = {
            mousemove: function (event) {
                event = normalizeEvent(this.dom, event);
                this.trigger(&apos;mousemove&apos;, event);
            },
            mouseout: function (event) {
                event = normalizeEvent(this.dom, event);
                var element = event.toElement || event.relatedTarget;
                if (element != this.dom) {
                    while (element &amp;&amp; element.nodeType != 9) {
                        // &#x5FFD;&#x7565;&#x5305;&#x542B;&#x5728;root&#x4E2D;&#x7684;dom&#x5F15;&#x8D77;&#x7684;mouseOut
                        if (element === this.dom) {
                            return;
                        }
                        element = element.parentNode;
                    }
                }
                this.trigger(&apos;mouseout&apos;, event);
            },
            touchstart: function (event) {
                // Default mouse behaviour should not be disabled here.
                // For example, page may needs to be slided.
                event = normalizeEvent(this.dom, event);
                this._lastTouchMoment = new Date();
                processGesture(this, event, &apos;start&apos;);
                // &#x5E73;&#x677F;&#x8865;&#x5145;&#x4E00;&#x6B21;findHover
                // this._mobileFindFixed(event);
                // Trigger mousemove and mousedown
                domHandlers.mousemove.call(this, event);
                domHandlers.mousedown.call(this, event);
                setTouchTimer(this);
            },
            touchmove: function (event) {
                event = normalizeEvent(this.dom, event);
                processGesture(this, event, &apos;change&apos;);
                // Mouse move should always be triggered no matter whether
                // there is gestrue event, because mouse move and pinch may
                // be used at the same time.
                domHandlers.mousemove.call(this, event);
                setTouchTimer(this);
            },
            touchend: function (event) {
                event = normalizeEvent(this.dom, event);
                processGesture(this, event, &apos;end&apos;);
                domHandlers.mouseup.call(this, event);
                // click event should always be triggered no matter whether
                // there is gestrue event. System click can not be prevented.
                if (+new Date() - this._lastTouchMoment &lt; TOUCH_CLICK_DELAY) {
                    domHandlers.click.call(this, event);
                }
                setTouchTimer(this);
            }
        };
    // Common handlers
    zrUtil.each([
        &apos;click&apos;,
        &apos;mousedown&apos;,
        &apos;mouseup&apos;,
        &apos;mousewheel&apos;,
        &apos;dblclick&apos;
    ], function (name) {
        domHandlers[name] = function (event) {
            event = normalizeEvent(this.dom, event);
            this.trigger(name, event);
        };
    });
    /**
     * &#x4E3A;&#x63A7;&#x5236;&#x7C7B;&#x5B9E;&#x4F8B;&#x521D;&#x59CB;&#x5316;dom &#x4E8B;&#x4EF6;&#x5904;&#x7406;&#x51FD;&#x6570;
     *
     * @inner
     * @param {module:zrender/Handler} instance &#x63A7;&#x5236;&#x7C7B;&#x5B9E;&#x4F8B;
     */
    function initDomHandler(instance) {
        for (var i = 0; i &lt; touchHandlerNames.length; i++) {
            var name = touchHandlerNames[i];
            instance._handlers[name] = zrUtil.bind(domHandlers[name], instance);
        }
        for (var i = 0; i &lt; mouseHandlerNames.length; i++) {
            var name = mouseHandlerNames[i];
            instance._handlers[name] = makeMouseHandler(domHandlers[name], instance);
        }
        function makeMouseHandler(fn, instance) {
            return function () {
                if (instance._touching) {
                    return;
                }
                return fn.apply(instance, arguments);
            };
        }
    }
    function HandlerDomProxy(dom) {
        Eventful.call(this);
        this.dom = dom;
        /**
         * @private
         * @type {boolean}
         */
        this._touching = false;
        /**
         * @private
         * @type {number}
         */
        this._touchTimer;
        /**
         * @private
         * @type {module:zrender/core/GestureMgr}
         */
        this._gestureMgr = new GestureMgr();
        this._handlers = {};
        initDomHandler(this);
        if (useTouchEvent()) {
            mountHandlers(touchHandlerNames, this);    // Handler of &apos;mouseout&apos; event is needed in touch mode, which will be mounted below.
                                                       // addEventListener(root, &apos;mouseout&apos;, this._mouseoutHandler);
        }
        // Considering some devices that both enable touch and mouse event (like MS Surface
        // and lenovo X240, @see #2350), we make mouse event be always listened, otherwise
        // mouse event can not be handle in those devices.
        mountHandlers(mouseHandlerNames, this);
        function mountHandlers(handlerNames, instance) {
            zrUtil.each(handlerNames, function (name) {
                addEventListener(dom, eventNameFix(name), instance._handlers[name]);
            }, instance);
        }
    }
    var handlerDomProxyProto = HandlerDomProxy.prototype;
    handlerDomProxyProto.dispose = function () {
        var handlerNames = mouseHandlerNames.concat(touchHandlerNames);
        for (var i = 0; i &lt; handlerNames.length; i++) {
            var name = handlerNames[i];
            removeEventListener(this.dom, eventNameFix(name), this._handlers[name]);
        }
    };
    handlerDomProxyProto.setCursor = function (cursorStyle) {
        this.dom.style.cursor = cursorStyle || &apos;default&apos;;
    };
    zrUtil.mixin(HandlerDomProxy, Eventful);
    return HandlerDomProxy;
});
define(&apos;zrender/Storage&apos;, [&apos;require&apos;, &apos;./core/util&apos;, &apos;./core/env&apos;, &apos;./container/Group&apos;, &apos;./core/timsort&apos;], function (require) {
    &apos;use strict&apos;;
    var util = require(&apos;./core/util&apos;);
    var env = require(&apos;./core/env&apos;);
    var Group = require(&apos;./container/Group&apos;);
    // Use timsort because in most case elements are partially sorted
    // https://jsfiddle.net/pissang/jr4x7mdm/8/
    var timsort = require(&apos;./core/timsort&apos;);
    function shapeCompareFunc(a, b) {
        if (a.zlevel === b.zlevel) {
            if (a.z === b.z) {
                // if (a.z2 === b.z2) {
                //     // FIXME Slow has renderidx compare
                //     // http://stackoverflow.com/questions/20883421/sorting-in-javascript-should-every-compare-function-have-a-return-0-statement
                //     // https://github.com/v8/v8/blob/47cce544a31ed5577ffe2963f67acb4144ee0232/src/js/array.js#L1012
                //     return a.__renderidx - b.__renderidx;
                // }
                return a.z2 - b.z2;
            }
            return a.z - b.z;
        }
        return a.zlevel - b.zlevel;
    }
    /**
     * &#x5185;&#x5BB9;&#x4ED3;&#x5E93; (M)
     * @alias module:zrender/Storage
     * @constructor
     */
    var Storage = function () {
        // &#x6240;&#x6709;&#x5E38;&#x89C4;&#x5F62;&#x72B6;&#xFF0C;id&#x7D22;&#x5F15;&#x7684;map
        this._elements = {};
        this._roots = [];
        this._displayList = [];
        this._displayListLen = 0;
    };
    Storage.prototype = {
        constructor: Storage,
        traverse: function (cb, context) {
            for (var i = 0; i &lt; this._roots.length; i++) {
                this._roots[i].traverse(cb, context);
            }
        },
        getDisplayList: function (update, includeIgnore) {
            includeIgnore = includeIgnore || false;
            if (update) {
                this.updateDisplayList(includeIgnore);
            }
            return this._displayList;
        },
        updateDisplayList: function (includeIgnore) {
            this._displayListLen = 0;
            var roots = this._roots;
            var displayList = this._displayList;
            for (var i = 0, len = roots.length; i &lt; len; i++) {
                this._updateAndAddDisplayable(roots[i], null, includeIgnore);
            }
            displayList.length = this._displayListLen;
            // for (var i = 0, len = displayList.length; i &lt; len; i++) {
            //     displayList[i].__renderidx = i;
            // }
            // displayList.sort(shapeCompareFunc);
            env.canvasSupported &amp;&amp; timsort(displayList, shapeCompareFunc);
        },
        _updateAndAddDisplayable: function (el, clipPaths, includeIgnore) {
            if (el.ignore &amp;&amp; !includeIgnore) {
                return;
            }
            el.beforeUpdate();
            if (el.__dirty) {
                el.update();
            }
            el.afterUpdate();
            var clipPath = el.clipPath;
            if (clipPath) {
                // clipPath &#x7684;&#x53D8;&#x6362;&#x662F;&#x57FA;&#x4E8E; group &#x7684;&#x53D8;&#x6362;
                clipPath.parent = el;
                clipPath.updateTransform();
                // FIXME &#x6548;&#x7387;&#x5F71;&#x54CD;
                if (clipPaths) {
                    clipPaths = clipPaths.slice();
                    clipPaths.push(clipPath);
                } else {
                    clipPaths = [clipPath];
                }
            }
            if (el.isGroup) {
                var children = el._children;
                for (var i = 0; i &lt; children.length; i++) {
                    var child = children[i];
                    // Force to mark as dirty if group is dirty
                    // FIXME __dirtyPath ?
                    if (el.__dirty) {
                        child.__dirty = true;
                    }
                    this._updateAndAddDisplayable(child, clipPaths, includeIgnore);
                }
                // Mark group clean here
                el.__dirty = false;
            } else {
                el.__clipPaths = clipPaths;
                this._displayList[this._displayListLen++] = el;
            }
        },
        addRoot: function (el) {
            // Element has been added
            if (this._elements[el.id]) {
                return;
            }
            if (el instanceof Group) {
                el.addChildrenToStorage(this);
            }
            this.addToMap(el);
            this._roots.push(el);
        },
        delRoot: function (elId) {
            if (elId == null) {
                // &#x4E0D;&#x6307;&#x5B9A;elId&#x6E05;&#x7A7A;
                for (var i = 0; i &lt; this._roots.length; i++) {
                    var root = this._roots[i];
                    if (root instanceof Group) {
                        root.delChildrenFromStorage(this);
                    }
                }
                this._elements = {};
                this._roots = [];
                this._displayList = [];
                this._displayListLen = 0;
                return;
            }
            if (elId instanceof Array) {
                for (var i = 0, l = elId.length; i &lt; l; i++) {
                    this.delRoot(elId[i]);
                }
                return;
            }
            var el;
            if (typeof elId == &apos;string&apos;) {
                el = this._elements[elId];
            } else {
                el = elId;
            }
            var idx = util.indexOf(this._roots, el);
            if (idx &gt;= 0) {
                this.delFromMap(el.id);
                this._roots.splice(idx, 1);
                if (el instanceof Group) {
                    el.delChildrenFromStorage(this);
                }
            }
        },
        addToMap: function (el) {
            if (el instanceof Group) {
                el.__storage = this;
            }
            el.dirty();
            this._elements[el.id] = el;
            return this;
        },
        get: function (elId) {
            return this._elements[elId];
        },
        delFromMap: function (elId) {
            var elements = this._elements;
            var el = elements[elId];
            if (el) {
                delete elements[elId];
                if (el instanceof Group) {
                    el.__storage = null;
                }
            }
            return this;
        },
        dispose: function () {
            this._elements = this._renderList = this._roots = null;
        },
        displayableSortFunc: shapeCompareFunc
    };
    return Storage;
});
define(&apos;zrender/animation/Animation&apos;, [&apos;require&apos;, &apos;../core/util&apos;, &apos;../core/event&apos;, &apos;./requestAnimationFrame&apos;, &apos;./Animator&apos;], function (require) {
    &apos;use strict&apos;;
    var util = require(&apos;../core/util&apos;);
    var Dispatcher = require(&apos;../core/event&apos;).Dispatcher;
    var requestAnimationFrame = require(&apos;./requestAnimationFrame&apos;);
    var Animator = require(&apos;./Animator&apos;);
    /**
     * @typedef {Object} IZRenderStage
     * @property {Function} update
     */
    /**
     * @alias module:zrender/animation/Animation
     * @constructor
     * @param {Object} [options]
     * @param {Function} [options.onframe]
     * @param {IZRenderStage} [options.stage]
     * @example
     *     var animation = new Animation();
     *     var obj = {
     *         x: 100,
     *         y: 100
     *     };
     *     animation.animate(node.position)
     *         .when(1000, {
     *             x: 500,
     *             y: 500
     *         })
     *         .when(2000, {
     *             x: 100,
     *             y: 100
     *         })
     *         .start(&apos;spline&apos;);
     */
    var Animation = function (options) {
        options = options || {};
        this.stage = options.stage || {};
        this.onframe = options.onframe || function () {
        };
        // private properties
        this._clips = [];
        this._running = false;
        this._time = 0;
        Dispatcher.call(this);
    };
    Animation.prototype = {
        constructor: Animation,
        addClip: function (clip) {
            this._clips.push(clip);
        },
        addAnimator: function (animator) {
            animator.animation = this;
            var clips = animator.getClips();
            for (var i = 0; i &lt; clips.length; i++) {
                this.addClip(clips[i]);
            }
        },
        removeClip: function (clip) {
            var idx = util.indexOf(this._clips, clip);
            if (idx &gt;= 0) {
                this._clips.splice(idx, 1);
            }
        },
        removeAnimator: function (animator) {
            var clips = animator.getClips();
            for (var i = 0; i &lt; clips.length; i++) {
                this.removeClip(clips[i]);
            }
            animator.animation = null;
        },
        _update: function () {
            var time = new Date().getTime();
            var delta = time - this._time;
            var clips = this._clips;
            var len = clips.length;
            var deferredEvents = [];
            var deferredClips = [];
            for (var i = 0; i &lt; len; i++) {
                var clip = clips[i];
                var e = clip.step(time);
                // Throw out the events need to be called after
                // stage.update, like destroy
                if (e) {
                    deferredEvents.push(e);
                    deferredClips.push(clip);
                }
            }
            // Remove the finished clip
            for (var i = 0; i &lt; len;) {
                if (clips[i]._needsRemove) {
                    clips[i] = clips[len - 1];
                    clips.pop();
                    len--;
                } else {
                    i++;
                }
            }
            len = deferredEvents.length;
            for (var i = 0; i &lt; len; i++) {
                deferredClips[i].fire(deferredEvents[i]);
            }
            this._time = time;
            this.onframe(delta);
            this.trigger(&apos;frame&apos;, delta);
            if (this.stage.update) {
                this.stage.update();
            }
        },
        start: function () {
            var self = this;
            this._running = true;
            function step() {
                if (self._running) {
                    requestAnimationFrame(step);
                    self._update();
                }
            }
            this._time = new Date().getTime();
            requestAnimationFrame(step);
        },
        stop: function () {
            this._running = false;
        },
        clear: function () {
            this._clips = [];
        },
        animate: function (target, options) {
            options = options || {};
            var animator = new Animator(target, options.loop, options.getter, options.setter);
            return animator;
        }
    };
    util.mixin(Animation, Dispatcher);
    return Animation;
});
define(&apos;zrender/mixin/Draggable&apos;, [&apos;require&apos;], function (require) {
    function Draggable() {
        this.on(&apos;mousedown&apos;, this._dragStart, this);
        this.on(&apos;mousemove&apos;, this._drag, this);
        this.on(&apos;mouseup&apos;, this._dragEnd, this);
        this.on(&apos;globalout&apos;, this._dragEnd, this);    // this._dropTarget = null;
                                                      // this._draggingTarget = null;
                                                      // this._x = 0;
                                                      // this._y = 0;
    }
    Draggable.prototype = {
        constructor: Draggable,
        _dragStart: function (e) {
            var draggingTarget = e.target;
            if (draggingTarget &amp;&amp; draggingTarget.draggable) {
                this._draggingTarget = draggingTarget;
                draggingTarget.dragging = true;
                this._x = e.offsetX;
                this._y = e.offsetY;
                this.dispatchToElement(draggingTarget, &apos;dragstart&apos;, e.event);
            }
        },
        _drag: function (e) {
            var draggingTarget = this._draggingTarget;
            if (draggingTarget) {
                var x = e.offsetX;
                var y = e.offsetY;
                var dx = x - this._x;
                var dy = y - this._y;
                this._x = x;
                this._y = y;
                draggingTarget.drift(dx, dy, e);
                this.dispatchToElement(draggingTarget, &apos;drag&apos;, e.event);
                var dropTarget = this.findHover(x, y, draggingTarget);
                var lastDropTarget = this._dropTarget;
                this._dropTarget = dropTarget;
                if (draggingTarget !== dropTarget) {
                    if (lastDropTarget &amp;&amp; dropTarget !== lastDropTarget) {
                        this.dispatchToElement(lastDropTarget, &apos;dragleave&apos;, e.event);
                    }
                    if (dropTarget &amp;&amp; dropTarget !== lastDropTarget) {
                        this.dispatchToElement(dropTarget, &apos;dragenter&apos;, e.event);
                    }
                }
            }
        },
        _dragEnd: function (e) {
            var draggingTarget = this._draggingTarget;
            if (draggingTarget) {
                draggingTarget.dragging = false;
            }
            this.dispatchToElement(draggingTarget, &apos;dragend&apos;, e.event);
            if (this._dropTarget) {
                this.dispatchToElement(this._dropTarget, &apos;drop&apos;, e.event);
            }
            this._draggingTarget = null;
            this._dropTarget = null;
        }
    };
    return Draggable;
});
define(&apos;zrender/core/event&apos;, [&apos;require&apos;, &apos;../mixin/Eventful&apos;], function (require) {
    &apos;use strict&apos;;
    var Eventful = require(&apos;../mixin/Eventful&apos;);
    var isDomLevel2 = typeof window !== &apos;undefined&apos; &amp;&amp; !!window.addEventListener;
    function getBoundingClientRect(el) {
        // BlackBerry 5, iOS 3 (original iPhone) don&apos;t have getBoundingRect
        return el.getBoundingClientRect ? el.getBoundingClientRect() : {
            left: 0,
            top: 0
        };
    }
    function clientToLocal(el, e, out) {
        // clientX/clientY is according to view port.
        var box = getBoundingClientRect(el);
        out = out || {};
        out.zrX = e.clientX - box.left;
        out.zrY = e.clientY - box.top;
        return out;
    }
    /**
     * &#x5982;&#x679C;&#x5B58;&#x5728;&#x7B2C;&#x4E09;&#x65B9;&#x5D4C;&#x5165;&#x7684;&#x4E00;&#x4E9B;dom&#x89E6;&#x53D1;&#x7684;&#x4E8B;&#x4EF6;&#xFF0C;&#x6216;touch&#x4E8B;&#x4EF6;&#xFF0C;&#x9700;&#x8981;&#x8F6C;&#x6362;&#x4E00;&#x4E0B;&#x4E8B;&#x4EF6;&#x5750;&#x6807;
     */
    function normalizeEvent(el, e) {
        e = e || window.event;
        if (e.zrX != null) {
            return e;
        }
        var eventType = e.type;
        var isTouch = eventType &amp;&amp; eventType.indexOf(&apos;touch&apos;) &gt;= 0;
        if (!isTouch) {
            clientToLocal(el, e, e);
            e.zrDelta = e.wheelDelta ? e.wheelDelta / 120 : -(e.detail || 0) / 3;
        } else {
            var touch = eventType != &apos;touchend&apos; ? e.targetTouches[0] : e.changedTouches[0];
            touch &amp;&amp; clientToLocal(el, touch, e);
        }
        return e;
    }
    function addEventListener(el, name, handler) {
        if (isDomLevel2) {
            el.addEventListener(name, handler);
        } else {
            el.attachEvent(&apos;on&apos; + name, handler);
        }
    }
    function removeEventListener(el, name, handler) {
        if (isDomLevel2) {
            el.removeEventListener(name, handler);
        } else {
            el.detachEvent(&apos;on&apos; + name, handler);
        }
    }
    /**
     * &#x505C;&#x6B62;&#x5192;&#x6CE1;&#x548C;&#x963B;&#x6B62;&#x9ED8;&#x8BA4;&#x884C;&#x4E3A;
     * @memberOf module:zrender/core/event
     * @method
     * @param {Event} e : event&#x5BF9;&#x8C61;
     */
    var stop = isDomLevel2 ? function (e) {
            e.preventDefault();
            e.stopPropagation();
            e.cancelBubble = true;
        } : function (e) {
            e.returnValue = false;
            e.cancelBubble = true;
        };
    return {
        clientToLocal: clientToLocal,
        normalizeEvent: normalizeEvent,
        addEventListener: addEventListener,
        removeEventListener: removeEventListener,
        stop: stop,
        Dispatcher: Eventful
    };
});
define(&apos;zrender/animation/requestAnimationFrame&apos;, [&apos;require&apos;], function (require) {
    return typeof window !== &apos;undefined&apos; &amp;&amp; (window.requestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame) || function (func) {
        setTimeout(func, 16);
    };
});
define(&apos;zrender/core/GestureMgr&apos;, [&apos;require&apos;, &apos;./event&apos;], function (require) {
    &apos;use strict&apos;;
    var eventUtil = require(&apos;./event&apos;);
    var GestureMgr = function () {
        /**
         * @private
         * @type {Array.<object>}
         */
        this._track = [];
    };
    GestureMgr.prototype = {
        constructor: GestureMgr,
        recognize: function (event, target, root) {
            this._doTrack(event, target, root);
            return this._recognize(event);
        },
        clear: function () {
            this._track.length = 0;
            return this;
        },
        _doTrack: function (event, target, root) {
            var touches = event.touches;
            if (!touches) {
                return;
            }
            var trackItem = {
                    points: [],
                    touches: [],
                    target: target,
                    event: event
                };
            for (var i = 0, len = touches.length; i &lt; len; i++) {
                var touch = touches[i];
                var pos = eventUtil.clientToLocal(root, touch);
                trackItem.points.push([
                    pos.zrX,
                    pos.zrY
                ]);
                trackItem.touches.push(touch);
            }
            this._track.push(trackItem);
        },
        _recognize: function (event) {
            for (var eventName in recognizers) {
                if (recognizers.hasOwnProperty(eventName)) {
                    var gestureInfo = recognizers[eventName](this._track, event);
                    if (gestureInfo) {
                        return gestureInfo;
                    }
                }
            }
        }
    };
    function dist(pointPair) {
        var dx = pointPair[1][0] - pointPair[0][0];
        var dy = pointPair[1][1] - pointPair[0][1];
        return Math.sqrt(dx * dx + dy * dy);
    }
    function center(pointPair) {
        return [
            (pointPair[0][0] + pointPair[1][0]) / 2,
            (pointPair[0][1] + pointPair[1][1]) / 2
        ];
    }
    var recognizers = {
            pinch: function (track, event) {
                var trackLen = track.length;
                if (!trackLen) {
                    return;
                }
                var pinchEnd = (track[trackLen - 1] || {}).points;
                var pinchPre = (track[trackLen - 2] || {}).points || pinchEnd;
                if (pinchPre &amp;&amp; pinchPre.length &gt; 1 &amp;&amp; pinchEnd &amp;&amp; pinchEnd.length &gt; 1) {
                    var pinchScale = dist(pinchEnd) / dist(pinchPre);
                    !isFinite(pinchScale) &amp;&amp; (pinchScale = 1);
                    event.pinchScale = pinchScale;
                    var pinchCenter = center(pinchEnd);
                    event.pinchX = pinchCenter[0];
                    event.pinchY = pinchCenter[1];
                    return {
                        type: &apos;pinch&apos;,
                        target: track[0].target,
                        event: event
                    };
                }
            }    // Only pinch currently.
        };
    return GestureMgr;
});
define(&apos;zrender/Layer&apos;, [&apos;require&apos;, &apos;./core/util&apos;, &apos;./config&apos;, &apos;./graphic/Style&apos;, &apos;./graphic/Pattern&apos;], function (require) {
    var util = require(&apos;./core/util&apos;);
    var config = require(&apos;./config&apos;);
    var Style = require(&apos;./graphic/Style&apos;);
    var Pattern = require(&apos;./graphic/Pattern&apos;);
    function returnFalse() {
        return false;
    }
    /**
     * &#x521B;&#x5EFA;dom
     *
     * @inner
     * @param {string} id dom id &#x5F85;&#x7528;
     * @param {string} type dom type&#xFF0C;such as canvas, div etc.
     * @param {Painter} painter painter instance
     * @param {number} number
     */
    function createDom(id, type, painter, dpr) {
        var newDom = document.createElement(type);
        var width = painter.getWidth();
        var height = painter.getHeight();
        var newDomStyle = newDom.style;
        // &#x6CA1;append&#x5462;&#xFF0C;&#x8BF7;&#x539F;&#x8C05;&#x6211;&#x8FD9;&#x6837;&#x5199;&#xFF0C;&#x6E05;&#x6670;~
        newDomStyle.position = &apos;absolute&apos;;
        newDomStyle.left = 0;
        newDomStyle.top = 0;
        newDomStyle.width = width + &apos;px&apos;;
        newDomStyle.height = height + &apos;px&apos;;
        newDom.width = width * dpr;
        newDom.height = height * dpr;
        // id&#x4E0D;&#x4F5C;&#x4E3A;&#x7D22;&#x5F15;&#x7528;&#xFF0C;&#x907F;&#x514D;&#x53EF;&#x80FD;&#x9020;&#x6210;&#x7684;&#x91CD;&#x540D;&#xFF0C;&#x5B9A;&#x4E49;&#x4E3A;&#x79C1;&#x6709;&#x5C5E;&#x6027;
        newDom.setAttribute(&apos;data-zr-dom-id&apos;, id);
        return newDom;
    }
    /**
     * @alias module:zrender/Layer
     * @constructor
     * @extends module:zrender/mixin/Transformable
     * @param {string} id
     * @param {module:zrender/Painter} painter
     * @param {number} [dpr]
     */
    var Layer = function (id, painter, dpr) {
        var dom;
        dpr = dpr || config.devicePixelRatio;
        if (typeof id === &apos;string&apos;) {
            dom = createDom(id, &apos;canvas&apos;, painter, dpr);
        }    // Not using isDom because in node it will return false
        else if (util.isObject(id)) {
            dom = id;
            id = dom.id;
        }
        this.id = id;
        this.dom = dom;
        var domStyle = dom.style;
        if (domStyle) {
            // Not in node
            dom.onselectstart = returnFalse;
            // &#x907F;&#x514D;&#x9875;&#x9762;&#x9009;&#x4E2D;&#x7684;&#x5C34;&#x5C2C;
            domStyle[&apos;-webkit-user-select&apos;] = &apos;none&apos;;
            domStyle[&apos;user-select&apos;] = &apos;none&apos;;
            domStyle[&apos;-webkit-touch-callout&apos;] = &apos;none&apos;;
            domStyle[&apos;-webkit-tap-highlight-color&apos;] = &apos;rgba(0,0,0,0)&apos;;
        }
        this.domBack = null;
        this.ctxBack = null;
        this.painter = painter;
        this.config = null;
        // Configs
        /**
         * &#x6BCF;&#x6B21;&#x6E05;&#x7A7A;&#x753B;&#x5E03;&#x7684;&#x989C;&#x8272;
         * @type {string}
         * @default 0
         */
        this.clearColor = 0;
        /**
         * &#x662F;&#x5426;&#x5F00;&#x542F;&#x52A8;&#x6001;&#x6A21;&#x7CCA;
         * @type {boolean}
         * @default false
         */
        this.motionBlur = false;
        /**
         * &#x5728;&#x5F00;&#x542F;&#x52A8;&#x6001;&#x6A21;&#x7CCA;&#x7684;&#x65F6;&#x5019;&#x4F7F;&#x7528;&#xFF0C;&#x4E0E;&#x4E0A;&#x4E00;&#x5E27;&#x6DF7;&#x5408;&#x7684;alpha&#x503C;&#xFF0C;&#x503C;&#x8D8A;&#x5927;&#x5C3E;&#x8FF9;&#x8D8A;&#x660E;&#x663E;
         * @type {number}
         * @default 0.7
         */
        this.lastFrameAlpha = 0.7;
        /**
         * Layer dpr
         * @type {number}
         */
        this.dpr = dpr;
    };
    Layer.prototype = {
        constructor: Layer,
        elCount: 0,
        __dirty: true,
        initContext: function () {
            this.ctx = this.dom.getContext(&apos;2d&apos;);
            var dpr = this.dpr;
            if (dpr != 1) {
                this.ctx.scale(dpr, dpr);
            }
        },
        createBackBuffer: function () {
            var dpr = this.dpr;
            this.domBack = createDom(&apos;back-&apos; + this.id, &apos;canvas&apos;, this.painter, dpr);
            this.ctxBack = this.domBack.getContext(&apos;2d&apos;);
            if (dpr != 1) {
                this.ctxBack.scale(dpr, dpr);
            }
        },
        resize: function (width, height) {
            var dpr = this.dpr;
            var dom = this.dom;
            var domStyle = dom.style;
            var domBack = this.domBack;
            domStyle.width = width + &apos;px&apos;;
            domStyle.height = height + &apos;px&apos;;
            dom.width = width * dpr;
            dom.height = height * dpr;
            if (dpr != 1) {
                this.ctx.scale(dpr, dpr);
            }
            if (domBack) {
                domBack.width = width * dpr;
                domBack.height = height * dpr;
                if (dpr != 1) {
                    this.ctxBack.scale(dpr, dpr);
                }
            }
        },
        clear: function (clearAll) {
            var dom = this.dom;
            var ctx = this.ctx;
            var width = dom.width;
            var height = dom.height;
            var clearColor = this.clearColor;
            var haveMotionBLur = this.motionBlur &amp;&amp; !clearAll;
            var lastFrameAlpha = this.lastFrameAlpha;
            var dpr = this.dpr;
            if (haveMotionBLur) {
                if (!this.domBack) {
                    this.createBackBuffer();
                }
                this.ctxBack.globalCompositeOperation = &apos;copy&apos;;
                this.ctxBack.drawImage(dom, 0, 0, width / dpr, height / dpr);
            }
            ctx.clearRect(0, 0, width / dpr, height / dpr);
            if (clearColor) {
                var clearColorGradientOrPattern;
                // Gradient
                if (clearColor.colorStops) {
                    // Cache canvas gradient
                    clearColorGradientOrPattern = clearColor.__canvasGradient || Style.getGradient(ctx, clearColor, {
                        x: 0,
                        y: 0,
                        width: width / dpr,
                        height: height / dpr
                    });
                    clearColor.__canvasGradient = clearColorGradientOrPattern;
                }    // Pattern
                else if (clearColor.image) {
                    clearColorGradientOrPattern = Pattern.prototype.getCanvasPattern.call(clearColor, ctx);
                }
                ctx.save();
                ctx.fillStyle = clearColorGradientOrPattern || clearColor;
                ctx.fillRect(0, 0, width / dpr, height / dpr);
                ctx.restore();
            }
            if (haveMotionBLur) {
                var domBack = this.domBack;
                ctx.save();
                ctx.globalAlpha = lastFrameAlpha;
                ctx.drawImage(domBack, 0, 0, width / dpr, height / dpr);
                ctx.restore();
            }
        }
    };
    return Layer;
});
define(&apos;echarts/preprocessor/helper/compatStyle&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var POSSIBLE_STYLES = [
            &apos;areaStyle&apos;,
            &apos;lineStyle&apos;,
            &apos;nodeStyle&apos;,
            &apos;linkStyle&apos;,
            &apos;chordStyle&apos;,
            &apos;label&apos;,
            &apos;labelLine&apos;
        ];
    function compatItemStyle(opt) {
        var itemStyleOpt = opt &amp;&amp; opt.itemStyle;
        if (itemStyleOpt) {
            zrUtil.each(POSSIBLE_STYLES, function (styleName) {
                var normalItemStyleOpt = itemStyleOpt.normal;
                var emphasisItemStyleOpt = itemStyleOpt.emphasis;
                if (normalItemStyleOpt &amp;&amp; normalItemStyleOpt[styleName]) {
                    opt[styleName] = opt[styleName] || {};
                    if (!opt[styleName].normal) {
                        opt[styleName].normal = normalItemStyleOpt[styleName];
                    } else {
                        zrUtil.merge(opt[styleName].normal, normalItemStyleOpt[styleName]);
                    }
                    normalItemStyleOpt[styleName] = null;
                }
                if (emphasisItemStyleOpt &amp;&amp; emphasisItemStyleOpt[styleName]) {
                    opt[styleName] = opt[styleName] || {};
                    if (!opt[styleName].emphasis) {
                        opt[styleName].emphasis = emphasisItemStyleOpt[styleName];
                    } else {
                        zrUtil.merge(opt[styleName].emphasis, emphasisItemStyleOpt[styleName]);
                    }
                    emphasisItemStyleOpt[styleName] = null;
                }
            });
        }
    }
    return function (seriesOpt) {
        if (!seriesOpt) {
            return;
        }
        compatItemStyle(seriesOpt);
        compatItemStyle(seriesOpt.markPoint);
        compatItemStyle(seriesOpt.markLine);
        var data = seriesOpt.data;
        if (data) {
            for (var i = 0; i &lt; data.length; i++) {
                compatItemStyle(data[i]);
            }
            // mark point data
            var markPoint = seriesOpt.markPoint;
            if (markPoint &amp;&amp; markPoint.data) {
                var mpData = markPoint.data;
                for (var i = 0; i &lt; mpData.length; i++) {
                    compatItemStyle(mpData[i]);
                }
            }
            // mark line data
            var markLine = seriesOpt.markLine;
            if (markLine &amp;&amp; markLine.data) {
                var mlData = markLine.data;
                for (var i = 0; i &lt; mlData.length; i++) {
                    if (zrUtil.isArray(mlData[i])) {
                        compatItemStyle(mlData[i][0]);
                        compatItemStyle(mlData[i][1]);
                    } else {
                        compatItemStyle(mlData[i]);
                    }
                }
            }
        }
    };
});
define(&apos;echarts/data/DataDiffer&apos;, [&apos;require&apos;], function (require) {
    &apos;use strict&apos;;
    function defaultKeyGetter(item) {
        return item;
    }
    function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter) {
        this._old = oldArr;
        this._new = newArr;
        this._oldKeyGetter = oldKeyGetter || defaultKeyGetter;
        this._newKeyGetter = newKeyGetter || defaultKeyGetter;
    }
    DataDiffer.prototype = {
        constructor: DataDiffer,
        add: function (func) {
            this._add = func;
            return this;
        },
        update: function (func) {
            this._update = func;
            return this;
        },
        remove: function (func) {
            this._remove = func;
            return this;
        },
        execute: function () {
            var oldArr = this._old;
            var newArr = this._new;
            var oldKeyGetter = this._oldKeyGetter;
            var newKeyGetter = this._newKeyGetter;
            var oldDataIndexMap = {};
            var newDataIndexMap = {};
            var oldDataKeyArr = [];
            var newDataKeyArr = [];
            var i;
            initIndexMap(oldArr, oldDataIndexMap, oldDataKeyArr, oldKeyGetter);
            initIndexMap(newArr, newDataIndexMap, newDataKeyArr, newKeyGetter);
            // Travel by inverted order to make sure order consistency
            // when duplicate keys exists (consider newDataIndex.pop() below).
            // For performance consideration, these code below do not look neat.
            for (i = 0; i &lt; oldArr.length; i++) {
                var key = oldDataKeyArr[i];
                var idx = newDataIndexMap[key];
                // idx can never be empty array here. see &apos;set null&apos; logic below.
                if (idx != null) {
                    // Consider there is duplicate key (for example, use dataItem.name as key).
                    // We should make sure every item in newArr and oldArr can be visited.
                    var len = idx.length;
                    if (len) {
                        len === 1 &amp;&amp; (newDataIndexMap[key] = null);
                        idx = idx.unshift();
                    } else {
                        newDataIndexMap[key] = null;
                    }
                    this._update &amp;&amp; this._update(idx, i);
                } else {
                    this._remove &amp;&amp; this._remove(i);
                }
            }
            for (var i = 0; i &lt; newDataKeyArr.length; i++) {
                var key = newDataKeyArr[i];
                if (newDataIndexMap.hasOwnProperty(key)) {
                    var idx = newDataIndexMap[key];
                    if (idx == null) {
                        continue;
                    }
                    // idx can never be empty array here. see &apos;set null&apos; logic above.
                    if (!idx.length) {
                        this._add &amp;&amp; this._add(idx);
                    } else {
                        for (var j = 0, len = idx.length; j &lt; len; j++) {
                            this._add &amp;&amp; this._add(idx[j]);
                        }
                    }
                }
            }
        }
    };
    function initIndexMap(arr, map, keyArr, keyGetter) {
        for (var i = 0; i &lt; arr.length; i++) {
            var key = keyGetter(arr[i], i);
            var existence = map[key];
            if (existence == null) {
                keyArr.push(key);
                map[key] = i;
            } else {
                if (!existence.length) {
                    map[key] = existence = [existence];
                }
                existence.push(i);
            }
        }
    }
    return DataDiffer;
});
define(&apos;echarts/component/helper/selectableMixin&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    return {
        updateSelectedMap: function (targetList) {
            this._selectTargetMap = zrUtil.reduce(targetList || [], function (targetMap, target) {
                targetMap[target.name] = target;
                return targetMap;
            }, {});
        },
        select: function (name) {
            var targetMap = this._selectTargetMap;
            var target = targetMap[name];
            var selectedMode = this.get(&apos;selectedMode&apos;);
            if (selectedMode === &apos;single&apos;) {
                zrUtil.each(targetMap, function (target) {
                    target.selected = false;
                });
            }
            target &amp;&amp; (target.selected = true);
        },
        unSelect: function (name) {
            var target = this._selectTargetMap[name];
            // var selectedMode = this.get(&apos;selectedMode&apos;);
            // selectedMode !== &apos;single&apos; &amp;&amp; target &amp;&amp; (target.selected = false);
            target &amp;&amp; (target.selected = false);
        },
        toggleSelected: function (name) {
            var target = this._selectTargetMap[name];
            if (target != null) {
                this[target.selected ? &apos;unSelect&apos; : &apos;select&apos;](name);
                return target.selected;
            }
        },
        isSelected: function (name) {
            var target = this._selectTargetMap[name];
            return target &amp;&amp; target.selected;
        }
    };
});
define(&apos;echarts/component/axis/AngleAxisView&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../../util/graphic&apos;, &apos;../../model/Model&apos;, &apos;../../echarts&apos;], function (require) {
    &apos;use strict&apos;;
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var graphic = require(&apos;../../util/graphic&apos;);
    var Model = require(&apos;../../model/Model&apos;);
    var elementList = [
            &apos;axisLine&apos;,
            &apos;axisLabel&apos;,
            &apos;axisTick&apos;,
            &apos;splitLine&apos;,
            &apos;splitArea&apos;
        ];
    function getAxisLineShape(polar, r0, r, angle) {
        var start = polar.coordToPoint([
                r0,
                angle
            ]);
        var end = polar.coordToPoint([
                r,
                angle
            ]);
        return {
            x1: start[0],
            y1: start[1],
            x2: end[0],
            y2: end[1]
        };
    }
    require(&apos;../../echarts&apos;).extendComponentView({
        type: &apos;angleAxis&apos;,
        render: function (angleAxisModel, ecModel) {
            this.group.removeAll();
            if (!angleAxisModel.get(&apos;show&apos;)) {
                return;
            }
            var polarModel = ecModel.getComponent(&apos;polar&apos;, angleAxisModel.get(&apos;polarIndex&apos;));
            var angleAxis = angleAxisModel.axis;
            var polar = polarModel.coordinateSystem;
            var radiusExtent = polar.getRadiusAxis().getExtent();
            var ticksAngles = angleAxis.getTicksCoords();
            if (angleAxis.type !== &apos;category&apos;) {
                // Remove the last tick which will overlap the first tick
                ticksAngles.pop();
            }
            zrUtil.each(elementList, function (name) {
                if (angleAxisModel.get(name + &apos;.show&apos;)) {
                    this[&apos;_&apos; + name](angleAxisModel, polar, ticksAngles, radiusExtent);
                }
            }, this);
        },
        _axisLine: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
            var lineStyleModel = angleAxisModel.getModel(&apos;axisLine.lineStyle&apos;);
            var circle = new graphic.Circle({
                    shape: {
                        cx: polar.cx,
                        cy: polar.cy,
                        r: radiusExtent[1]
                    },
                    style: lineStyleModel.getLineStyle(),
                    z2: 1,
                    silent: true
                });
            circle.style.fill = null;
            this.group.add(circle);
        },
        _axisTick: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
            var tickModel = angleAxisModel.getModel(&apos;axisTick&apos;);
            var tickLen = (tickModel.get(&apos;inside&apos;) ? -1 : 1) * tickModel.get(&apos;length&apos;);
            var lines = zrUtil.map(ticksAngles, function (tickAngle) {
                    return new graphic.Line({ shape: getAxisLineShape(polar, radiusExtent[1], radiusExtent[1] + tickLen, tickAngle) });
                });
            this.group.add(graphic.mergePath(lines, { style: zrUtil.defaults(tickModel.getModel(&apos;lineStyle&apos;).getLineStyle(), { stroke: angleAxisModel.get(&apos;axisLine.lineStyle.color&apos;) }) }));
        },
        _axisLabel: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
            var axis = angleAxisModel.axis;
            var categoryData = angleAxisModel.get(&apos;data&apos;);
            var labelModel = angleAxisModel.getModel(&apos;axisLabel&apos;);
            var axisTextStyleModel = labelModel.getModel(&apos;textStyle&apos;);
            var labels = angleAxisModel.getFormattedLabels();
            var labelMargin = labelModel.get(&apos;margin&apos;);
            var labelsAngles = axis.getLabelsCoords();
            // Use length of ticksAngles because it may remove the last tick to avoid overlapping
            for (var i = 0; i &lt; ticksAngles.length; i++) {
                var r = radiusExtent[1];
                var p = polar.coordToPoint([
                        r + labelMargin,
                        labelsAngles[i]
                    ]);
                var cx = polar.cx;
                var cy = polar.cy;
                var labelTextAlign = Math.abs(p[0] - cx) / r &lt; 0.3 ? &apos;center&apos; : p[0] &gt; cx ? &apos;left&apos; : &apos;right&apos;;
                var labelTextBaseline = Math.abs(p[1] - cy) / r &lt; 0.3 ? &apos;middle&apos; : p[1] &gt; cy ? &apos;top&apos; : &apos;bottom&apos;;
                var textStyleModel = axisTextStyleModel;
                if (categoryData &amp;&amp; categoryData[i] &amp;&amp; categoryData[i].textStyle) {
                    textStyleModel = new Model(categoryData[i].textStyle, axisTextStyleModel);
                }
                this.group.add(new graphic.Text({
                    style: {
                        x: p[0],
                        y: p[1],
                        fill: textStyleModel.getTextColor() || angleAxisModel.get(&apos;axisLine.lineStyle.color&apos;),
                        text: labels[i],
                        textAlign: labelTextAlign,
                        textVerticalAlign: labelTextBaseline,
                        textFont: textStyleModel.getFont()
                    },
                    silent: true
                }));
            }
        },
        _splitLine: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
            var splitLineModel = angleAxisModel.getModel(&apos;splitLine&apos;);
            var lineStyleModel = splitLineModel.getModel(&apos;lineStyle&apos;);
            var lineColors = lineStyleModel.get(&apos;color&apos;);
            var lineCount = 0;
            lineColors = lineColors instanceof Array ? lineColors : [lineColors];
            var splitLines = [];
            for (var i = 0; i &lt; ticksAngles.length; i++) {
                var colorIndex = lineCount++ % lineColors.length;
                splitLines[colorIndex] = splitLines[colorIndex] || [];
                splitLines[colorIndex].push(new graphic.Line({ shape: getAxisLineShape(polar, radiusExtent[0], radiusExtent[1], ticksAngles[i]) }));
            }
            // Simple optimization
            // Batching the lines if color are the same
            for (var i = 0; i &lt; splitLines.length; i++) {
                this.group.add(graphic.mergePath(splitLines[i], {
                    style: zrUtil.defaults({ stroke: lineColors[i % lineColors.length] }, lineStyleModel.getLineStyle()),
                    silent: true,
                    z: angleAxisModel.get(&apos;z&apos;)
                }));
            }
        },
        _splitArea: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
            var splitAreaModel = angleAxisModel.getModel(&apos;splitArea&apos;);
            var areaStyleModel = splitAreaModel.getModel(&apos;areaStyle&apos;);
            var areaColors = areaStyleModel.get(&apos;color&apos;);
            var lineCount = 0;
            areaColors = areaColors instanceof Array ? areaColors : [areaColors];
            var splitAreas = [];
            var RADIAN = Math.PI / 180;
            var prevAngle = -ticksAngles[0] * RADIAN;
            var r0 = Math.min(radiusExtent[0], radiusExtent[1]);
            var r1 = Math.max(radiusExtent[0], radiusExtent[1]);
            var clockwise = angleAxisModel.get(&apos;clockwise&apos;);
            for (var i = 1; i &lt; ticksAngles.length; i++) {
                var colorIndex = lineCount++ % areaColors.length;
                splitAreas[colorIndex] = splitAreas[colorIndex] || [];
                splitAreas[colorIndex].push(new graphic.Sector({
                    shape: {
                        cx: polar.cx,
                        cy: polar.cy,
                        r0: r0,
                        r: r1,
                        startAngle: prevAngle,
                        endAngle: -ticksAngles[i] * RADIAN,
                        clockwise: clockwise
                    },
                    silent: true
                }));
                prevAngle = -ticksAngles[i] * RADIAN;
            }
            // Simple optimization
            // Batching the lines if color are the same
            for (var i = 0; i &lt; splitAreas.length; i++) {
                this.group.add(graphic.mergePath(splitAreas[i], {
                    style: zrUtil.defaults({ fill: areaColors[i % areaColors.length] }, areaStyleModel.getAreaStyle()),
                    silent: true
                }));
            }
        }
    });
});
define(&apos;echarts/data/helper/completeDimensions&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    /**
     * Complete the dimensions array guessed from the data structure.
     * @param  {Array.<string>} dimensions      Necessary dimensions, like [&apos;x&apos;, &apos;y&apos;]
     * @param  {Array} data                     Data list. [[1, 2, 3], [2, 3, 4]]
     * @param  {Array.<string>} defaultNames    Default names to fill not necessary dimensions, like [&apos;value&apos;]
     * @param  {string} extraPrefix             Prefix of name when filling the left dimensions.
     * @return {Array.<string>}
     */
    function completeDimensions(dimensions, data, defaultNames, extraPrefix) {
        if (!data) {
            return dimensions;
        }
        var value0 = retrieveValue(data[0]);
        var dimSize = zrUtil.isArray(value0) &amp;&amp; value0.length || 1;
        defaultNames = defaultNames || [];
        extraPrefix = extraPrefix || &apos;extra&apos;;
        for (var i = 0; i &lt; dimSize; i++) {
            if (!dimensions[i]) {
                var name = defaultNames[i] || extraPrefix + (i - defaultNames.length);
                dimensions[i] = guessOrdinal(data, i) ? {
                    type: &apos;ordinal&apos;,
                    name: name
                } : name;
            }
        }
        return dimensions;
    }
    // The rule should not be complex, otherwise user might not
    // be able to known where the data is wrong.
    var guessOrdinal = completeDimensions.guessOrdinal = function (data, dimIndex) {
            for (var i = 0, len = data.length; i &lt; len; i++) {
                var value = retrieveValue(data[i]);
                if (!zrUtil.isArray(value)) {
                    return false;
                }
                var value = value[dimIndex];
                if (value != null &amp;&amp; isFinite(value)) {
                    return false;
                } else if (zrUtil.isString(value) &amp;&amp; value !== &apos;-&apos;) {
                    return true;
                }
            }
            return false;
        };
    function retrieveValue(o) {
        return zrUtil.isArray(o) ? o : zrUtil.isObject(o) ? o.value : o;
    }
    return completeDimensions;
});
define(&apos;echarts/coord/radar/RadarModel&apos;, [&apos;require&apos;, &apos;../axisDefault&apos;, &apos;../../model/Model&apos;, &apos;zrender/core/util&apos;, &apos;../axisModelCommonMixin&apos;, &apos;../../echarts&apos;], function (require) {
    var axisDefault = require(&apos;../axisDefault&apos;);
    var valueAxisDefault = axisDefault.valueAxis;
    var Model = require(&apos;../../model/Model&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var axisModelCommonMixin = require(&apos;../axisModelCommonMixin&apos;);
    function defaultsShow(opt, show) {
        return zrUtil.defaults({ show: show }, opt);
    }
    var RadarModel = require(&apos;../../echarts&apos;).extendComponentModel({
            type: &apos;radar&apos;,
            optionUpdated: function () {
                var boundaryGap = this.get(&apos;boundaryGap&apos;);
                var splitNumber = this.get(&apos;splitNumber&apos;);
                var scale = this.get(&apos;scale&apos;);
                var axisLine = this.get(&apos;axisLine&apos;);
                var axisTick = this.get(&apos;axisTick&apos;);
                var axisLabel = this.get(&apos;axisLabel&apos;);
                var nameTextStyle = this.get(&apos;name.textStyle&apos;);
                var showName = this.get(&apos;name.show&apos;);
                var nameFormatter = this.get(&apos;name.formatter&apos;);
                var nameGap = this.get(&apos;nameGap&apos;);
                var indicatorModels = zrUtil.map(this.get(&apos;indicator&apos;) || [], function (indicatorOpt) {
                        // PENDING
                        if (indicatorOpt.max != null &amp;&amp; indicatorOpt.max &gt; 0) {
                            indicatorOpt.min = 0;
                        } else if (indicatorOpt.min != null &amp;&amp; indicatorOpt.min &lt; 0) {
                            indicatorOpt.max = 0;
                        }
                        // Use same configuration
                        indicatorOpt = zrUtil.merge(zrUtil.clone(indicatorOpt), {
                            boundaryGap: boundaryGap,
                            splitNumber: splitNumber,
                            scale: scale,
                            axisLine: axisLine,
                            axisTick: axisTick,
                            axisLabel: axisLabel,
                            name: indicatorOpt.text,
                            nameLocation: &apos;end&apos;,
                            nameGap: nameGap,
                            nameTextStyle: nameTextStyle
                        }, false);
                        if (!showName) {
                            indicatorOpt.name = &apos;&apos;;
                        }
                        if (typeof nameFormatter === &apos;string&apos;) {
                            indicatorOpt.name = nameFormatter.replace(&apos;{value}&apos;, indicatorOpt.name);
                        } else if (typeof nameFormatter === &apos;function&apos;) {
                            indicatorOpt.name = nameFormatter(indicatorOpt.name, indicatorOpt);
                        }
                        return zrUtil.extend(new Model(indicatorOpt, null, this.ecModel), axisModelCommonMixin);
                    }, this);
                this.getIndicatorModels = function () {
                    return indicatorModels;
                };
            },
            defaultOption: {
                zlevel: 0,
                z: 0,
                center: [
                    &apos;50%&apos;,
                    &apos;50%&apos;
                ],
                radius: &apos;75%&apos;,
                startAngle: 90,
                name: { show: true },
                boundaryGap: [
                    0,
                    0
                ],
                splitNumber: 5,
                nameGap: 15,
                scale: false,
                shape: &apos;polygon&apos;,
                axisLine: zrUtil.merge({ lineStyle: { color: &apos;#bbb&apos; } }, valueAxisDefault.axisLine),
                axisLabel: defaultsShow(valueAxisDefault.axisLabel, false),
                axisTick: defaultsShow(valueAxisDefault.axisTick, false),
                splitLine: defaultsShow(valueAxisDefault.splitLine, true),
                splitArea: defaultsShow(valueAxisDefault.splitArea, true),
                indicator: []
            }
        });
    return RadarModel;
});
define(&apos;echarts/coord/radar/Radar&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;./IndicatorAxis&apos;, &apos;../../scale/Interval&apos;, &apos;../../util/number&apos;, &apos;../axisHelper&apos;, &apos;../../CoordinateSystem&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var IndicatorAxis = require(&apos;./IndicatorAxis&apos;);
    var IntervalScale = require(&apos;../../scale/Interval&apos;);
    var numberUtil = require(&apos;../../util/number&apos;);
    var axisHelper = require(&apos;../axisHelper&apos;);
    function Radar(radarModel, ecModel, api) {
        this._model = radarModel;
        /**
         * Radar dimensions
         * @type {Array.<string>}
         */
        this.dimensions = [];
        this._indicatorAxes = zrUtil.map(radarModel.getIndicatorModels(), function (indicatorModel, idx) {
            var dim = &apos;indicator_&apos; + idx;
            var indicatorAxis = new IndicatorAxis(dim, new IntervalScale());
            indicatorAxis.name = indicatorModel.get(&apos;name&apos;);
            // Inject model and axis
            indicatorAxis.model = indicatorModel;
            indicatorModel.axis = indicatorAxis;
            this.dimensions.push(dim);
            return indicatorAxis;
        }, this);
        this.resize(radarModel, api);
        /**
         * @type {number}
         * @readOnly
         */
        this.cx;
        /**
         * @type {number}
         * @readOnly
         */
        this.cy;
        /**
         * @type {number}
         * @readOnly
         */
        this.r;
        /**
         * @type {number}
         * @readOnly
         */
        this.startAngle;
    }
    Radar.prototype.getIndicatorAxes = function () {
        return this._indicatorAxes;
    };
    Radar.prototype.dataToPoint = function (value, indicatorIndex) {
        var indicatorAxis = this._indicatorAxes[indicatorIndex];
        return this.coordToPoint(indicatorAxis.dataToCoord(value), indicatorIndex);
    };
    Radar.prototype.coordToPoint = function (coord, indicatorIndex) {
        var indicatorAxis = this._indicatorAxes[indicatorIndex];
        var angle = indicatorAxis.angle;
        var x = this.cx + coord * Math.cos(angle);
        var y = this.cy - coord * Math.sin(angle);
        return [
            x,
            y
        ];
    };
    Radar.prototype.pointToData = function (pt) {
        var dx = pt[0] - this.cx;
        var dy = pt[1] - this.cy;
        var radius = Math.sqrt(dx * dx + dy * dy);
        dx /= radius;
        dy /= radius;
        var radian = Math.atan2(-dy, dx);
        // Find the closest angle
        // FIXME index can calculated directly
        var minRadianDiff = Infinity;
        var closestAxis;
        var closestAxisIdx = -1;
        for (var i = 0; i &lt; this._indicatorAxes.length; i++) {
            var indicatorAxis = this._indicatorAxes[i];
            var diff = Math.abs(radian - indicatorAxis.angle);
            if (diff &lt; minRadianDiff) {
                closestAxis = indicatorAxis;
                closestAxisIdx = i;
                minRadianDiff = diff;
            }
        }
        return [
            closestAxisIdx,
            +(closestAxis &amp;&amp; closestAxis.coodToData(radius))
        ];
    };
    Radar.prototype.resize = function (radarModel, api) {
        var center = radarModel.get(&apos;center&apos;);
        var viewWidth = api.getWidth();
        var viewHeight = api.getHeight();
        var viewSize = Math.min(viewWidth, viewHeight) / 2;
        this.cx = numberUtil.parsePercent(center[0], viewWidth);
        this.cy = numberUtil.parsePercent(center[1], viewHeight);
        this.startAngle = radarModel.get(&apos;startAngle&apos;) * Math.PI / 180;
        this.r = numberUtil.parsePercent(radarModel.get(&apos;radius&apos;), viewSize);
        zrUtil.each(this._indicatorAxes, function (indicatorAxis, idx) {
            indicatorAxis.setExtent(0, this.r);
            var angle = this.startAngle + idx * Math.PI * 2 / this._indicatorAxes.length;
            // Normalize to [-PI, PI]
            angle = Math.atan2(Math.sin(angle), Math.cos(angle));
            indicatorAxis.angle = angle;
        }, this);
    };
    Radar.prototype.update = function (ecModel, api) {
        var indicatorAxes = this._indicatorAxes;
        var radarModel = this._model;
        zrUtil.each(indicatorAxes, function (indicatorAxis) {
            indicatorAxis.scale.setExtent(Infinity, -Infinity);
        });
        ecModel.eachSeriesByType(&apos;radar&apos;, function (radarSeries, idx) {
            if (radarSeries.get(&apos;coordinateSystem&apos;) !== &apos;radar&apos; || ecModel.getComponent(&apos;radar&apos;, radarSeries.get(&apos;radarIndex&apos;)) !== radarModel) {
                return;
            }
            var data = radarSeries.getData();
            zrUtil.each(indicatorAxes, function (indicatorAxis) {
                indicatorAxis.scale.unionExtent(data.getDataExtent(indicatorAxis.dim));
            });
        }, this);
        var splitNumber = radarModel.get(&apos;splitNumber&apos;);
        function increaseInterval(interval) {
            var exp10 = Math.pow(10, Math.floor(Math.log(interval) / Math.LN10));
            // Increase interval
            var f = interval / exp10;
            if (f === 2) {
                f = 5;
            } else {
                // f is 2 or 5
                f *= 2;
            }
            return f * exp10;
        }
        // Force all the axis fixing the maxSplitNumber.
        zrUtil.each(indicatorAxes, function (indicatorAxis, idx) {
            var rawExtent = axisHelper.getScaleExtent(indicatorAxis, indicatorAxis.model);
            axisHelper.niceScaleExtent(indicatorAxis, indicatorAxis.model);
            var axisModel = indicatorAxis.model;
            var scale = indicatorAxis.scale;
            var fixedMin = axisModel.get(&apos;min&apos;);
            var fixedMax = axisModel.get(&apos;max&apos;);
            var interval = scale.getInterval();
            if (fixedMin != null &amp;&amp; fixedMax != null) {
                // User set min, max, divide to get new interval
                // FIXME precision
                scale.setInterval((fixedMax - fixedMin) / splitNumber);
            } else if (fixedMin != null) {
                var max;
                // User set min, expand extent on the other side
                do {
                    max = fixedMin + interval * splitNumber;
                    scale.setExtent(+fixedMin, max);
                    // Interval must been set after extent
                    // FIXME
                    scale.setInterval(interval);
                    interval = increaseInterval(interval);
                } while (max &lt; rawExtent[1] &amp;&amp; isFinite(max) &amp;&amp; isFinite(rawExtent[1]));
            } else if (fixedMax != null) {
                var min;
                // User set min, expand extent on the other side
                do {
                    min = fixedMax - interval * splitNumber;
                    scale.setExtent(min, +fixedMax);
                    scale.setInterval(interval);
                    interval = increaseInterval(interval);
                } while (min &gt; rawExtent[0] &amp;&amp; isFinite(min) &amp;&amp; isFinite(rawExtent[0]));
            } else {
                var nicedSplitNumber = scale.getTicks().length - 1;
                if (nicedSplitNumber &gt; splitNumber) {
                    interval = increaseInterval(interval);
                }
                // PENDING
                var center = Math.round((rawExtent[0] + rawExtent[1]) / 2 / interval) * interval;
                var halfSplitNumber = Math.round(splitNumber / 2);
                scale.setExtent(numberUtil.round(center - halfSplitNumber * interval), numberUtil.round(center + (splitNumber - halfSplitNumber) * interval));
                scale.setInterval(interval);
            }
        });
    };
    /**
     * Radar dimensions is based on the data
     * @type {Array}
     */
    Radar.dimensions = [];
    Radar.create = function (ecModel, api) {
        var radarList = [];
        ecModel.eachComponent(&apos;radar&apos;, function (radarModel) {
            var radar = new Radar(radarModel, ecModel, api);
            radarList.push(radar);
            radarModel.coordinateSystem = radar;
        });
        ecModel.eachSeriesByType(&apos;radar&apos;, function (radarSeries) {
            if (radarSeries.get(&apos;coordinateSystem&apos;) === &apos;radar&apos;) {
                // Inject coordinate system
                radarSeries.coordinateSystem = radarList[radarSeries.get(&apos;radarIndex&apos;) || 0];
            }
        });
        return radarList;
    };
    require(&apos;../../CoordinateSystem&apos;).register(&apos;radar&apos;, Radar);
    return Radar;
});
define(&apos;echarts/component/radar/RadarView&apos;, [&apos;require&apos;, &apos;../axis/AxisBuilder&apos;, &apos;zrender/core/util&apos;, &apos;../../util/graphic&apos;, &apos;../../echarts&apos;], function (require) {
    var AxisBuilder = require(&apos;../axis/AxisBuilder&apos;);
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var graphic = require(&apos;../../util/graphic&apos;);
    var axisBuilderAttrs = [
            &apos;axisLine&apos;,
            &apos;axisLabel&apos;,
            &apos;axisTick&apos;,
            &apos;axisName&apos;
        ];
    return require(&apos;../../echarts&apos;).extendComponentView({
        type: &apos;radar&apos;,
        render: function (radarModel, ecModel, api) {
            var group = this.group;
            group.removeAll();
            this._buildAxes(radarModel);
            this._buildSplitLineAndArea(radarModel);
        },
        _buildAxes: function (radarModel) {
            var radar = radarModel.coordinateSystem;
            var indicatorAxes = radar.getIndicatorAxes();
            var axisBuilders = zrUtil.map(indicatorAxes, function (indicatorAxis) {
                    var axisBuilder = new AxisBuilder(indicatorAxis.model, {
                            position: [
                                radar.cx,
                                radar.cy
                            ],
                            rotation: indicatorAxis.angle,
                            labelDirection: -1,
                            tickDirection: -1,
                            nameDirection: 1
                        });
                    return axisBuilder;
                });
            zrUtil.each(axisBuilders, function (axisBuilder) {
                zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);
                this.group.add(axisBuilder.getGroup());
            }, this);
        },
        _buildSplitLineAndArea: function (radarModel) {
            var radar = radarModel.coordinateSystem;
            var splitNumber = radarModel.get(&apos;splitNumber&apos;);
            var indicatorAxes = radar.getIndicatorAxes();
            if (!indicatorAxes.length) {
                return;
            }
            var shape = radarModel.get(&apos;shape&apos;);
            var splitLineModel = radarModel.getModel(&apos;splitLine&apos;);
            var splitAreaModel = radarModel.getModel(&apos;splitArea&apos;);
            var lineStyleModel = splitLineModel.getModel(&apos;lineStyle&apos;);
            var areaStyleModel = splitAreaModel.getModel(&apos;areaStyle&apos;);
            var showSplitLine = splitLineModel.get(&apos;show&apos;);
            var showSplitArea = splitAreaModel.get(&apos;show&apos;);
            var splitLineColors = lineStyleModel.get(&apos;color&apos;);
            var splitAreaColors = areaStyleModel.get(&apos;color&apos;);
            splitLineColors = zrUtil.isArray(splitLineColors) ? splitLineColors : [splitLineColors];
            splitAreaColors = zrUtil.isArray(splitAreaColors) ? splitAreaColors : [splitAreaColors];
            var splitLines = [];
            var splitAreas = [];
            function getColorIndex(areaOrLine, areaOrLineColorList, idx) {
                var colorIndex = idx % areaOrLineColorList.length;
                areaOrLine[colorIndex] = areaOrLine[colorIndex] || [];
                return colorIndex;
            }
            if (shape === &apos;circle&apos;) {
                var ticksRadius = indicatorAxes[0].getTicksCoords();
                var cx = radar.cx;
                var cy = radar.cy;
                for (var i = 0; i &lt; ticksRadius.length; i++) {
                    if (showSplitLine) {
                        var colorIndex = getColorIndex(splitLines, splitLineColors, i);
                        splitLines[colorIndex].push(new graphic.Circle({
                            shape: {
                                cx: cx,
                                cy: cy,
                                r: ticksRadius[i]
                            }
                        }));
                    }
                    if (showSplitArea &amp;&amp; i &lt; ticksRadius.length - 1) {
                        var colorIndex = getColorIndex(splitAreas, splitAreaColors, i);
                        splitAreas[colorIndex].push(new graphic.Ring({
                            shape: {
                                cx: cx,
                                cy: cy,
                                r0: ticksRadius[i],
                                r: ticksRadius[i + 1]
                            }
                        }));
                    }
                }
            }    // Polyyon
            else {
                var axesTicksPoints = zrUtil.map(indicatorAxes, function (indicatorAxis, idx) {
                        var ticksCoords = indicatorAxis.getTicksCoords();
                        return zrUtil.map(ticksCoords, function (tickCoord) {
                            return radar.coordToPoint(tickCoord, idx);
                        });
                    });
                var prevPoints = [];
                for (var i = 0; i <= 0="" 2="" 3="" 4="" 5="" splitnumber;="" i++)="" {="" var="" points="[];" for="" (var="" j="0;" <="" indicatoraxes.length;="" j++)="" points.push(axestickspoints[j][i]);="" }="" close="" points.push(points[0].slice());="" if="" (showsplitline)="" colorindex="getColorIndex(splitLines," splitlinecolors,="" i);="" splitlines[colorindex].push(new="" graphic.polyline({="" shape:="" points:="" }));="" (showsplitarea="" &&="" prevpoints)="" splitareacolors,="" i="" -="" 1);="" splitareas[colorindex].push(new="" graphic.polygon({="" points.concat(prevpoints)="" prevpoints="points.slice().reverse();" linestyle="lineStyleModel.getLineStyle();" areastyle="areaStyleModel.getAreaStyle();" add="" splitarea="" before="" splitline="" zrutil.each(splitareas,="" function="" (splitareas,="" idx)="" this.group.add(graphic.mergepath(splitareas,="" style:="" zrutil.defaults({="" stroke:="" 'none',="" fill:="" splitareacolors[idx="" %="" splitareacolors.length]="" },="" areastyle),="" silent:="" true="" this);="" zrutil.each(splitlines,="" (splitlines,="" this.group.add(graphic.mergepath(splitlines,="" splitlinecolors[idx="" splitlinecolors.length]="" linestyle),="" });="" define('echarts="" component="" helper="" listcomponent',="" ['require',="" '..="" ..="" util="" layout',="" format',="" graphic'],="" (require)="" list="" layout="" formatutil="require(&apos;../../util/format&apos;);" graphic="require(&apos;../../util/graphic&apos;);" positiongroup(group,="" model,="" api)="" layout.positiongroup(group,="" model.getboxlayoutparams(),="" width:="" api.getwidth(),="" height:="" api.getheight()="" model.get('padding'));="" return="" layout:="" (group,="" componentmodel,="" rect="layout.getLayoutRect(componentModel.getBoxLayoutParams()," componentmodel.get('padding'));="" layout.box(componentmodel.get('orient'),="" group,="" componentmodel.get('itemgap'),="" rect.width,="" rect.height);="" api);="" addbackground:="" componentmodel)="" padding="formatUtil.normalizeCssArray(componentModel.get(&apos;padding&apos;));" boundingrect="group.getBoundingRect();" style="componentModel.getItemStyle([" 'color',="" 'opacity'="" ]);="" style.fill="componentModel.get(&apos;backgroundColor&apos;);" graphic.rect({="" x:="" boundingrect.x="" padding[3],="" y:="" boundingrect.y="" padding[0],="" boundingrect.width="" +="" padding[1]="" boundingrect.height="" padding[0]="" padding[2]="" style,="" true,="" z2:="" -1="" graphic.subpixeloptimizerect(rect);="" group.add(rect);="" };="" symbol',="" '.="" graphic',="" 'zrender="" core="" boundingrect'],="" 'use="" strict';="" **="" *="" triangle="" shape="" @inner="" type:="" 'triangle',="" cx:="" 0,="" cy:="" buildpath:="" (path,="" shape)="" cx="shape.cx;" cy="shape.cy;" width="shape.width" 2;="" height="shape.height" path.moveto(cx,="" height);="" path.lineto(cx="" width,="" path.closepath();="" diamond="" 'diamond',="" cy);="" path.lineto(cx,="" pin="" 'pin',="" x="shape.x;" y="shape.y;" w="shape.width" 3;="" must="" be="" larger="" than="" h="Math.max(w," shape.height);="" r="w" dist="" on="" with="" tangent="" point="" and="" circle="" center="" dy="r" (h="" r);="" dy;="" angle="Math.asin(dy" dx="Math.cos(angle)" r;="" tanx="Math.sin(angle);" tany="Math.cos(angle);" path.arc(x,="" cy,="" r,="" math.pi="" angle,="" angle);="" cplen="r" 0.6;="" cplen2="r" 0.7;="" path.beziercurveto(x="" cplen,="" x,="" cplen2,="" y);="" path.beziercurveto(x,="" dx,="" dy);="" arrow="" 'arrow',="" (ctx,="" ctx.moveto(x,="" ctx.lineto(x="" ctx.lineto(x,="" 3);="" ctx.closepath();="" map="" of="" path="" contructors="" @type="" {object.<string,="" module:zrender="">}
     */
    var symbolCtors = {
            line: graphic.Line,
            rect: graphic.Rect,
            roundRect: graphic.Rect,
            square: graphic.Rect,
            circle: graphic.Circle,
            diamond: Diamond,
            pin: Pin,
            arrow: Arrow,
            triangle: Triangle
        };
    var symbolShapeMakers = {
            line: function (x, y, w, h, shape) {
                // FIXME
                shape.x1 = x;
                shape.y1 = y + h / 2;
                shape.x2 = x + w;
                shape.y2 = y + h / 2;
            },
            rect: function (x, y, w, h, shape) {
                shape.x = x;
                shape.y = y;
                shape.width = w;
                shape.height = h;
            },
            roundRect: function (x, y, w, h, shape) {
                shape.x = x;
                shape.y = y;
                shape.width = w;
                shape.height = h;
                shape.r = Math.min(w, h) / 4;
            },
            square: function (x, y, w, h, shape) {
                var size = Math.min(w, h);
                shape.x = x;
                shape.y = y;
                shape.width = size;
                shape.height = size;
            },
            circle: function (x, y, w, h, shape) {
                // Put circle in the center of square
                shape.cx = x + w / 2;
                shape.cy = y + h / 2;
                shape.r = Math.min(w, h) / 2;
            },
            diamond: function (x, y, w, h, shape) {
                shape.cx = x + w / 2;
                shape.cy = y + h / 2;
                shape.width = w;
                shape.height = h;
            },
            pin: function (x, y, w, h, shape) {
                shape.x = x + w / 2;
                shape.y = y + h / 2;
                shape.width = w;
                shape.height = h;
            },
            arrow: function (x, y, w, h, shape) {
                shape.x = x + w / 2;
                shape.y = y + h / 2;
                shape.width = w;
                shape.height = h;
            },
            triangle: function (x, y, w, h, shape) {
                shape.cx = x + w / 2;
                shape.cy = y + h / 2;
                shape.width = w;
                shape.height = h;
            }
        };
    var symbolBuildProxies = {};
    for (var name in symbolCtors) {
        symbolBuildProxies[name] = new symbolCtors[name]();
    }
    var Symbol = graphic.extendShape({
            type: &apos;symbol&apos;,
            shape: {
                symbolType: &apos;&apos;,
                x: 0,
                y: 0,
                width: 0,
                height: 0
            },
            beforeBrush: function () {
                var style = this.style;
                var shape = this.shape;
                // FIXME
                if (shape.symbolType === &apos;pin&apos; &amp;&amp; style.textPosition === &apos;inside&apos;) {
                    style.textPosition = [
                        &apos;50%&apos;,
                        &apos;40%&apos;
                    ];
                    style.textAlign = &apos;center&apos;;
                    style.textVerticalAlign = &apos;middle&apos;;
                }
            },
            buildPath: function (ctx, shape, inBundle) {
                var symbolType = shape.symbolType;
                var proxySymbol = symbolBuildProxies[symbolType];
                if (shape.symbolType !== &apos;none&apos;) {
                    if (!proxySymbol) {
                        // Default rect
                        symbolType = &apos;rect&apos;;
                        proxySymbol = symbolBuildProxies[symbolType];
                    }
                    symbolShapeMakers[symbolType](shape.x, shape.y, shape.width, shape.height, proxySymbol.shape);
                    proxySymbol.buildPath(ctx, proxySymbol.shape, inBundle);
                }
            }
        });
    // Provide setColor helper method to avoid determine if set the fill or stroke outside
    var symbolPathSetColor = function (color) {
        if (this.type !== &apos;image&apos;) {
            var symbolStyle = this.style;
            var symbolShape = this.shape;
            if (symbolShape &amp;&amp; symbolShape.symbolType === &apos;line&apos;) {
                symbolStyle.stroke = color;
            } else if (this.__isEmptyBrush) {
                symbolStyle.stroke = color;
                symbolStyle.fill = &apos;#fff&apos;;
            } else {
                // FIXME &#x5224;&#x65AD;&#x56FE;&#x5F62;&#x9ED8;&#x8BA4;&#x662F;&#x586B;&#x5145;&#x8FD8;&#x662F;&#x63CF;&#x8FB9;&#xFF0C;&#x4F7F;&#x7528; onlyStroke ?
                symbolStyle.fill &amp;&amp; (symbolStyle.fill = color);
                symbolStyle.stroke &amp;&amp; (symbolStyle.stroke = color);
            }
            this.dirty(false);
        }
    };
    var symbolUtil = {
            createSymbol: function (symbolType, x, y, w, h, color) {
                var isEmpty = symbolType.indexOf(&apos;empty&apos;) === 0;
                if (isEmpty) {
                    symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6);
                }
                var symbolPath;
                if (symbolType.indexOf(&apos;image://&apos;) === 0) {
                    symbolPath = new graphic.Image({
                        style: {
                            image: symbolType.slice(8),
                            x: x,
                            y: y,
                            width: w,
                            height: h
                        }
                    });
                } else if (symbolType.indexOf(&apos;path://&apos;) === 0) {
                    symbolPath = graphic.makePath(symbolType.slice(7), {}, new BoundingRect(x, y, w, h));
                } else {
                    symbolPath = new Symbol({
                        shape: {
                            symbolType: symbolType,
                            x: x,
                            y: y,
                            width: w,
                            height: h
                        }
                    });
                }
                symbolPath.__isEmptyBrush = isEmpty;
                symbolPath.setColor = symbolPathSetColor;
                symbolPath.setColor(color);
                return symbolPath;
            }
        };
    return symbolUtil;
});
define(&apos;echarts/component/axis/RadiusAxisView&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../../util/graphic&apos;, &apos;./AxisBuilder&apos;, &apos;../../echarts&apos;], function (require) {
    &apos;use strict&apos;;
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var graphic = require(&apos;../../util/graphic&apos;);
    var AxisBuilder = require(&apos;./AxisBuilder&apos;);
    var axisBuilderAttrs = [
            &apos;axisLine&apos;,
            &apos;axisLabel&apos;,
            &apos;axisTick&apos;,
            &apos;axisName&apos;
        ];
    var selfBuilderAttrs = [
            &apos;splitLine&apos;,
            &apos;splitArea&apos;
        ];
    require(&apos;../../echarts&apos;).extendComponentView({
        type: &apos;radiusAxis&apos;,
        render: function (radiusAxisModel, ecModel) {
            this.group.removeAll();
            if (!radiusAxisModel.get(&apos;show&apos;)) {
                return;
            }
            var polarModel = ecModel.getComponent(&apos;polar&apos;, radiusAxisModel.get(&apos;polarIndex&apos;));
            var angleAxis = polarModel.coordinateSystem.getAngleAxis();
            var radiusAxis = radiusAxisModel.axis;
            var polar = polarModel.coordinateSystem;
            var ticksCoords = radiusAxis.getTicksCoords();
            var axisAngle = angleAxis.getExtent()[0];
            var radiusExtent = radiusAxis.getExtent();
            var layout = layoutAxis(polar, radiusAxisModel, axisAngle);
            var axisBuilder = new AxisBuilder(radiusAxisModel, layout);
            zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);
            this.group.add(axisBuilder.getGroup());
            zrUtil.each(selfBuilderAttrs, function (name) {
                if (radiusAxisModel.get(name + &apos;.show&apos;)) {
                    this[&apos;_&apos; + name](radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords);
                }
            }, this);
        },
        _splitLine: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
            var splitLineModel = radiusAxisModel.getModel(&apos;splitLine&apos;);
            var lineStyleModel = splitLineModel.getModel(&apos;lineStyle&apos;);
            var lineColors = lineStyleModel.get(&apos;color&apos;);
            var lineCount = 0;
            lineColors = lineColors instanceof Array ? lineColors : [lineColors];
            var splitLines = [];
            for (var i = 0; i &lt; ticksCoords.length; i++) {
                var colorIndex = lineCount++ % lineColors.length;
                splitLines[colorIndex] = splitLines[colorIndex] || [];
                splitLines[colorIndex].push(new graphic.Circle({
                    shape: {
                        cx: polar.cx,
                        cy: polar.cy,
                        r: ticksCoords[i]
                    },
                    silent: true
                }));
            }
            // Simple optimization
            // Batching the lines if color are the same
            for (var i = 0; i &lt; splitLines.length; i++) {
                this.group.add(graphic.mergePath(splitLines[i], {
                    style: zrUtil.defaults({
                        stroke: lineColors[i % lineColors.length],
                        fill: null
                    }, lineStyleModel.getLineStyle()),
                    silent: true
                }));
            }
        },
        _splitArea: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
            var splitAreaModel = radiusAxisModel.getModel(&apos;splitArea&apos;);
            var areaStyleModel = splitAreaModel.getModel(&apos;areaStyle&apos;);
            var areaColors = areaStyleModel.get(&apos;color&apos;);
            var lineCount = 0;
            areaColors = areaColors instanceof Array ? areaColors : [areaColors];
            var splitAreas = [];
            var prevRadius = ticksCoords[0];
            for (var i = 1; i &lt; ticksCoords.length; i++) {
                var colorIndex = lineCount++ % areaColors.length;
                splitAreas[colorIndex] = splitAreas[colorIndex] || [];
                splitAreas[colorIndex].push(new graphic.Sector({
                    shape: {
                        cx: polar.cx,
                        cy: polar.cy,
                        r0: prevRadius,
                        r: ticksCoords[i],
                        startAngle: 0,
                        endAngle: Math.PI * 2
                    },
                    silent: true
                }));
                prevRadius = ticksCoords[i];
            }
            // Simple optimization
            // Batching the lines if color are the same
            for (var i = 0; i &lt; splitAreas.length; i++) {
                this.group.add(graphic.mergePath(splitAreas[i], {
                    style: zrUtil.defaults({ fill: areaColors[i % areaColors.length] }, areaStyleModel.getAreaStyle()),
                    silent: true
                }));
            }
        }
    });
    /**
     * @inner
     */
    function layoutAxis(polar, radiusAxisModel, axisAngle) {
        return {
            position: [
                polar.cx,
                polar.cy
            ],
            rotation: axisAngle / 180 * Math.PI,
            labelDirection: -1,
            tickDirection: -1,
            nameDirection: 1,
            labelRotation: radiusAxisModel.getModel(&apos;axisLabel&apos;).get(&apos;rotate&apos;),
            z2: 1
        };
    }
});
define(&apos;echarts/component/tooltip/TooltipContent&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;zrender/tool/color&apos;, &apos;zrender/core/event&apos;, &apos;../../util/format&apos;, &apos;zrender/core/env&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var zrColor = require(&apos;zrender/tool/color&apos;);
    var eventUtil = require(&apos;zrender/core/event&apos;);
    var formatUtil = require(&apos;../../util/format&apos;);
    var each = zrUtil.each;
    var toCamelCase = formatUtil.toCamelCase;
    var env = require(&apos;zrender/core/env&apos;);
    var vendors = [
            &apos;&apos;,
            &apos;-webkit-&apos;,
            &apos;-moz-&apos;,
            &apos;-o-&apos;
        ];
    var gCssText = &apos;position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;&apos;;
    /**
     * @param {number} duration
     * @return {string}
     * @inner
     */
    function assembleTransition(duration) {
        var transitionCurve = &apos;cubic-bezier(0.23, 1, 0.32, 1)&apos;;
        var transitionText = &apos;left &apos; + duration + &apos;s &apos; + transitionCurve + &apos;,&apos; + &apos;top &apos; + duration + &apos;s &apos; + transitionCurve;
        return zrUtil.map(vendors, function (vendorPrefix) {
            return vendorPrefix + &apos;transition:&apos; + transitionText;
        }).join(&apos;;&apos;);
    }
    /**
     * @param {Object} textStyle
     * @return {string}
     * @inner
     */
    function assembleFont(textStyleModel) {
        var cssText = [];
        var fontSize = textStyleModel.get(&apos;fontSize&apos;);
        var color = textStyleModel.getTextColor();
        color &amp;&amp; cssText.push(&apos;color:&apos; + color);
        cssText.push(&apos;font:&apos; + textStyleModel.getFont());
        fontSize &amp;&amp; cssText.push(&apos;line-height:&apos; + Math.round(fontSize * 3 / 2) + &apos;px&apos;);
        each([
            &apos;decoration&apos;,
            &apos;align&apos;
        ], function (name) {
            var val = textStyleModel.get(name);
            val &amp;&amp; cssText.push(&apos;text-&apos; + name + &apos;:&apos; + val);
        });
        return cssText.join(&apos;;&apos;);
    }
    /**
     * @param {Object} tooltipModel
     * @return {string}
     * @inner
     */
    function assembleCssText(tooltipModel) {
        tooltipModel = tooltipModel;
        var cssText = [];
        var transitionDuration = tooltipModel.get(&apos;transitionDuration&apos;);
        var backgroundColor = tooltipModel.get(&apos;backgroundColor&apos;);
        var textStyleModel = tooltipModel.getModel(&apos;textStyle&apos;);
        var padding = tooltipModel.get(&apos;padding&apos;);
        // Animation transition
        transitionDuration &amp;&amp; cssText.push(assembleTransition(transitionDuration));
        if (backgroundColor) {
            if (env.canvasSupported) {
                cssText.push(&apos;background-Color:&apos; + backgroundColor);
            } else {
                // for ie
                cssText.push(&apos;background-Color:#&apos; + zrColor.toHex(backgroundColor));
                cssText.push(&apos;filter:alpha(opacity=70)&apos;);
            }
        }
        // Border style
        each([
            &apos;width&apos;,
            &apos;color&apos;,
            &apos;radius&apos;
        ], function (name) {
            var borderName = &apos;border-&apos; + name;
            var camelCase = toCamelCase(borderName);
            var val = tooltipModel.get(camelCase);
            val != null &amp;&amp; cssText.push(borderName + &apos;:&apos; + val + (name === &apos;color&apos; ? &apos;&apos; : &apos;px&apos;));
        });
        // Text style
        cssText.push(assembleFont(textStyleModel));
        // Padding
        if (padding != null) {
            cssText.push(&apos;padding:&apos; + formatUtil.normalizeCssArray(padding).join(&apos;px &apos;) + &apos;px&apos;);
        }
        return cssText.join(&apos;;&apos;) + &apos;;&apos;;
    }
    /**
     * @alias module:echarts/component/tooltip/TooltipContent
     * @constructor
     */
    function TooltipContent(container, api) {
        var el = document.createElement(&apos;div&apos;);
        var zr = api.getZr();
        this.el = el;
        this._x = api.getWidth() / 2;
        this._y = api.getHeight() / 2;
        container.appendChild(el);
        this._container = container;
        this._show = false;
        /**
         * @private
         */
        this._hideTimeout;
        var self = this;
        el.onmouseenter = function () {
            // clear the timeout in hideLater and keep showing tooltip
            if (self.enterable) {
                clearTimeout(self._hideTimeout);
                self._show = true;
            }
            self._inContent = true;
        };
        el.onmousemove = function (e) {
            if (!self.enterable) {
                // Try trigger zrender event to avoid mouse
                // in and out shape too frequently
                var handler = zr.handler;
                eventUtil.normalizeEvent(container, e);
                handler.dispatch(&apos;mousemove&apos;, e);
            }
        };
        el.onmouseleave = function () {
            if (self.enterable) {
                if (self._show) {
                    self.hideLater(self._hideDelay);
                }
            }
            self._inContent = false;
        };
        compromiseMobile(el, container);
    }
    function compromiseMobile(tooltipContentEl, container) {
        // Prevent default behavior on mobile. For example,
        // default pinch gesture will cause browser zoom.
        // We do not preventing event on tooltip contnet el,
        // because user may need customization in tooltip el.
        eventUtil.addEventListener(container, &apos;touchstart&apos;, preventDefault);
        eventUtil.addEventListener(container, &apos;touchmove&apos;, preventDefault);
        eventUtil.addEventListener(container, &apos;touchend&apos;, preventDefault);
        function preventDefault(e) {
            if (contains(e.target)) {
                e.preventDefault();
            }
        }
        function contains(targetEl) {
            while (targetEl &amp;&amp; targetEl !== container) {
                if (targetEl === tooltipContentEl) {
                    return true;
                }
                targetEl = targetEl.parentNode;
            }
        }
    }
    TooltipContent.prototype = {
        constructor: TooltipContent,
        enterable: true,
        update: function () {
            var container = this._container;
            var stl = container.currentStyle || document.defaultView.getComputedStyle(container);
            var domStyle = container.style;
            if (domStyle.position !== &apos;absolute&apos; &amp;&amp; stl.position !== &apos;absolute&apos;) {
                domStyle.position = &apos;relative&apos;;
            }    // Hide the tooltip
                 // PENDING
                 // this.hide();
        },
        show: function (tooltipModel) {
            clearTimeout(this._hideTimeout);
            var el = this.el;
            el.style.cssText = gCssText + assembleCssText(tooltipModel) + &apos;;left:&apos; + this._x + &apos;px;top:&apos; + this._y + &apos;px;&apos; + (tooltipModel.get(&apos;extraCssText&apos;) || &apos;&apos;);
            el.style.display = el.innerHTML ? &apos;block&apos; : &apos;none&apos;;
            this._show = true;
        },
        setContent: function (content) {
            var el = this.el;
            el.innerHTML = content;
            el.style.display = content ? &apos;block&apos; : &apos;none&apos;;
        },
        moveTo: function (x, y) {
            var style = this.el.style;
            style.left = x + &apos;px&apos;;
            style.top = y + &apos;px&apos;;
            this._x = x;
            this._y = y;
        },
        hide: function () {
            this.el.style.display = &apos;none&apos;;
            this._show = false;
        },
        hideLater: function (time) {
            if (this._show &amp;&amp; !(this._inContent &amp;&amp; this.enterable)) {
                if (time) {
                    this._hideDelay = time;
                    // Set show false to avoid invoke hideLater mutiple times
                    this._show = false;
                    this._hideTimeout = setTimeout(zrUtil.bind(this.hide, this), time);
                } else {
                    this.hide();
                }
            }
        },
        isShow: function () {
            return this._show;
        }
    };
    return TooltipContent;
});
define(&apos;echarts/chart/pie/labelLayout&apos;, [&apos;require&apos;, &apos;zrender/contain/text&apos;], function (require) {
    &apos;use strict&apos;;
    var textContain = require(&apos;zrender/contain/text&apos;);
    function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
        list.sort(function (a, b) {
            return a.y - b.y;
        });
        // &#x538B;
        function shiftDown(start, end, delta, dir) {
            for (var j = start; j &lt; end; j++) {
                list[j].y += delta;
                if (j &gt; start &amp;&amp; j + 1 &lt; end &amp;&amp; list[j + 1].y &gt; list[j].y + list[j].height) {
                    shiftUp(j, delta / 2);
                    return;
                }
            }
            shiftUp(end - 1, delta / 2);
        }
        // &#x5F39;
        function shiftUp(end, delta) {
            for (var j = end; j &gt;= 0; j--) {
                list[j].y -= delta;
                if (j &gt; 0 &amp;&amp; list[j].y &gt; list[j - 1].y + list[j - 1].height) {
                    break;
                }
            }
        }
        function changeX(list, isDownList, cx, cy, r, dir) {
            var lastDeltaX = dir &gt; 0 ? isDownList ? Number.MAX_VALUE : 0 : isDownList ? Number.MAX_VALUE : 0;
            // &#x4E0A;
            for (var i = 0, l = list.length; i &lt; l; i++) {
                // Not change x for center label
                if (list[i].position === &apos;center&apos;) {
                    continue;
                }
                var deltaY = Math.abs(list[i].y - cy);
                var length = list[i].len;
                var length2 = list[i].len2;
                var deltaX = deltaY &lt; r + length ? Math.sqrt((r + length + length2) * (r + length + length2) - deltaY * deltaY) : Math.abs(list[i].x - cx);
                if (isDownList &amp;&amp; deltaX &gt;= lastDeltaX) {
                    // &#x53F3;&#x4E0B;&#xFF0C;&#x5DE6;&#x4E0B;
                    deltaX = lastDeltaX - 10;
                }
                if (!isDownList &amp;&amp; deltaX <= lastdeltax)="" {="" 右上，左上="" deltax="lastDeltaX" +="" 10;="" }="" list[i].x="cx" *="" dir;="" lastdeltax="deltaX;" var="" lasty="0;" delta;="" len="list.length;" uplist="[];" downlist="[];" for="" (var="" i="0;" <="" len;="" i++)="" delta="list[i].y" -="" lasty;="" if="" (delta="" 0)="" shiftdown(i,="" len,="" -delta,="" dir);="" list[i].height;="" (viewheight="" shiftup(len="" 1,="" viewheight);="" (list[i].y="">= cy) {
                downList.push(list[i]);
            } else {
                upList.push(list[i]);
            }
        }
        changeX(upList, false, cx, cy, r, dir);
        changeX(downList, true, cx, cy, r, dir);
    }
    function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) {
        var leftList = [];
        var rightList = [];
        for (var i = 0; i &lt; labelLayoutList.length; i++) {
            if (labelLayoutList[i].x &lt; cx) {
                leftList.push(labelLayoutList[i]);
            } else {
                rightList.push(labelLayoutList[i]);
            }
        }
        adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight);
        adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight);
        for (var i = 0; i &lt; labelLayoutList.length; i++) {
            var linePoints = labelLayoutList[i].linePoints;
            if (linePoints) {
                var dist = linePoints[1][0] - linePoints[2][0];
                if (labelLayoutList[i].x &lt; cx) {
                    linePoints[2][0] = labelLayoutList[i].x + 3;
                } else {
                    linePoints[2][0] = labelLayoutList[i].x - 3;
                }
                linePoints[1][1] = linePoints[2][1] = labelLayoutList[i].y;
                linePoints[1][0] = linePoints[2][0] + dist;
            }
        }
    }
    return function (seriesModel, r, viewWidth, viewHeight) {
        var data = seriesModel.getData();
        var labelLayoutList = [];
        var cx;
        var cy;
        var hasLabelRotate = false;
        data.each(function (idx) {
            var layout = data.getItemLayout(idx);
            var itemModel = data.getItemModel(idx);
            var labelModel = itemModel.getModel(&apos;label.normal&apos;);
            // Use position in normal or emphasis
            var labelPosition = labelModel.get(&apos;position&apos;) || itemModel.get(&apos;label.emphasis.position&apos;);
            var labelLineModel = itemModel.getModel(&apos;labelLine.normal&apos;);
            var labelLineLen = labelLineModel.get(&apos;length&apos;);
            var labelLineLen2 = labelLineModel.get(&apos;length2&apos;);
            var midAngle = (layout.startAngle + layout.endAngle) / 2;
            var dx = Math.cos(midAngle);
            var dy = Math.sin(midAngle);
            var textX;
            var textY;
            var linePoints;
            var textAlign;
            cx = layout.cx;
            cy = layout.cy;
            var isLabelInside = labelPosition === &apos;inside&apos; || labelPosition === &apos;inner&apos;;
            if (labelPosition === &apos;center&apos;) {
                textX = layout.cx;
                textY = layout.cy;
                textAlign = &apos;center&apos;;
            } else {
                var x1 = (isLabelInside ? (layout.r + layout.r0) / 2 * dx : layout.r * dx) + cx;
                var y1 = (isLabelInside ? (layout.r + layout.r0) / 2 * dy : layout.r * dy) + cy;
                textX = x1 + dx * 3;
                textY = y1 + dy * 3;
                if (!isLabelInside) {
                    // For roseType
                    var x2 = x1 + dx * (labelLineLen + r - layout.r);
                    var y2 = y1 + dy * (labelLineLen + r - layout.r);
                    var x3 = x2 + (dx &lt; 0 ? -1 : 1) * labelLineLen2;
                    var y3 = y2;
                    textX = x3 + (dx &lt; 0 ? -5 : 5);
                    textY = y3;
                    linePoints = [
                        [
                            x1,
                            y1
                        ],
                        [
                            x2,
                            y2
                        ],
                        [
                            x3,
                            y3
                        ]
                    ];
                }
                textAlign = isLabelInside ? &apos;center&apos; : dx &gt; 0 ? &apos;left&apos; : &apos;right&apos;;
            }
            var font = labelModel.getModel(&apos;textStyle&apos;).getFont();
            var labelRotate = labelModel.get(&apos;rotate&apos;) ? dx &lt; 0 ? -midAngle + Math.PI : -midAngle : 0;
            var text = seriesModel.getFormattedLabel(idx, &apos;normal&apos;) || data.getName(idx);
            var textRect = textContain.getBoundingRect(text, font, textAlign, &apos;top&apos;);
            hasLabelRotate = !!labelRotate;
            layout.label = {
                x: textX,
                y: textY,
                position: labelPosition,
                height: textRect.height,
                len: labelLineLen,
                len2: labelLineLen2,
                linePoints: linePoints,
                textAlign: textAlign,
                verticalAlign: &apos;middle&apos;,
                font: font,
                rotation: labelRotate
            };
            // Not layout the inside label
            if (!isLabelInside) {
                labelLayoutList.push(layout.label);
            }
        });
        if (!hasLabelRotate &amp;&amp; seriesModel.get(&apos;avoidLabelOverlap&apos;)) {
            avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight);
        }
    };
});
define(&apos;echarts/coord/radar/IndicatorAxis&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../Axis&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var Axis = require(&apos;../Axis&apos;);
    function IndicatorAxis(dim, scale, radiusExtent) {
        Axis.call(this, dim, scale, radiusExtent);
        /**
         * Axis type
         *  - &apos;category&apos;
         *  - &apos;value&apos;
         *  - &apos;time&apos;
         *  - &apos;log&apos;
         * @type {string}
         */
        this.type = &apos;value&apos;;
        this.angle = 0;
        /**
         * Indicator name
         * @type {string}
         */
        this.name = &apos;&apos;;
        /**
         * @type {module:echarts/model/Model}
         */
        this.model;
    }
    zrUtil.inherits(IndicatorAxis, Axis);
    return IndicatorAxis;
});
define(&apos;echarts/component/axis/AxisBuilder&apos;, [&apos;require&apos;, &apos;zrender/core/util&apos;, &apos;../../util/format&apos;, &apos;../../util/graphic&apos;, &apos;../../model/Model&apos;, &apos;../../util/number&apos;, &apos;zrender/core/vector&apos;], function (require) {
    var zrUtil = require(&apos;zrender/core/util&apos;);
    var formatUtil = require(&apos;../../util/format&apos;);
    var graphic = require(&apos;../../util/graphic&apos;);
    var Model = require(&apos;../../model/Model&apos;);
    var numberUtil = require(&apos;../../util/number&apos;);
    var remRadian = numberUtil.remRadian;
    var isRadianAroundZero = numberUtil.isRadianAroundZero;
    var vec2 = require(&apos;zrender/core/vector&apos;);
    var v2ApplyTransform = vec2.applyTransform;
    var retrieve = zrUtil.retrieve;
    var PI = Math.PI;
    function makeAxisEventDataBase(axisModel) {
        var eventData = { componentType: axisModel.mainType };
        eventData[axisModel.mainType + &apos;Index&apos;] = axisModel.componentIndex;
        return eventData;
    }
    /**
     * A final axis is translated and rotated from a &quot;standard axis&quot;.
     * So opt.position and opt.rotation is required.
     *
     * A standard axis is and axis from [0, 0] to [0, axisExtent[1]],
     * for example: (0, 0) ------------&gt; (0, 50)
     *
     * nameDirection or tickDirection or labelDirection is 1 means tick
     * or label is below the standard axis, whereas is -1 means above
     * the standard axis. labelOffset means offset between label and axis,
     * which is useful when &apos;onZero&apos;, where axisLabel is in the grid and
     * label in outside grid.
     *
     * Tips: like always,
     * positive rotation represents anticlockwise, and negative rotation
     * represents clockwise.
     * The direction of position coordinate is the same as the direction
     * of screen coordinate.
     *
     * Do not need to consider axis &apos;inverse&apos;, which is auto processed by
     * axis extent.
     *
     * @param {module:zrender/container/Group} group
     * @param {Object} axisModel
     * @param {Object} opt Standard axis parameters.
     * @param {Array.<number>} opt.position [x, y]
     * @param {number} opt.rotation by radian
     * @param {number} [opt.nameDirection=1] 1 or -1 Used when nameLocation is &apos;middle&apos;.
     * @param {number} [opt.tickDirection=1] 1 or -1
     * @param {number} [opt.labelDirection=1] 1 or -1
     * @param {number} [opt.labelOffset=0] Usefull when onZero.
     * @param {string} [opt.axisLabelShow] default get from axisModel.
     * @param {string} [opt.axisName] default get from axisModel.
     * @param {number} [opt.axisNameAvailableWidth]
     * @param {number} [opt.labelRotation] by degree, default get from axisModel.
     * @param {number} [opt.labelInterval] Default label interval when label
     *                                     interval from model is null or &apos;auto&apos;.
     * @param {number} [opt.strokeContainThreshold] Default label interval when label
     */
    var AxisBuilder = function (axisModel, opt) {
        /**
         * @readOnly
         */
        this.opt = opt;
        /**
         * @readOnly
         */
        this.axisModel = axisModel;
        // Default value
        zrUtil.defaults(opt, {
            labelOffset: 0,
            nameDirection: 1,
            tickDirection: 1,
            labelDirection: 1,
            silent: true
        });
        /**
         * @readOnly
         */
        this.group = new graphic.Group();
        // FIXME Not use a seperate text group?
        var dumbGroup = new graphic.Group({
                position: opt.position.slice(),
                rotation: opt.rotation
            });
        // this.group.add(dumbGroup);
        // this._dumbGroup = dumbGroup;
        dumbGroup.updateTransform();
        this._transform = dumbGroup.transform;
        this._dumbGroup = dumbGroup;
    };
    AxisBuilder.prototype = {
        constructor: AxisBuilder,
        hasBuilder: function (name) {
            return !!builders[name];
        },
        add: function (name) {
            builders[name].call(this);
        },
        getGroup: function () {
            return this.group;
        }
    };
    var builders = {
            axisLine: function () {
                var opt = this.opt;
                var axisModel = this.axisModel;
                if (!axisModel.get(&apos;axisLine.show&apos;)) {
                    return;
                }
                var extent = this.axisModel.axis.getExtent();
                var matrix = this._transform;
                var pt1 = [
                        extent[0],
                        0
                    ];
                var pt2 = [
                        extent[1],
                        0
                    ];
                if (matrix) {
                    v2ApplyTransform(pt1, pt1, matrix);
                    v2ApplyTransform(pt2, pt2, matrix);
                }
                this.group.add(new graphic.Line(graphic.subPixelOptimizeLine({
                    anid: &apos;line&apos;,
                    shape: {
                        x1: pt1[0],
                        y1: pt1[1],
                        x2: pt2[0],
                        y2: pt2[1]
                    },
                    style: zrUtil.extend({ lineCap: &apos;round&apos; }, axisModel.getModel(&apos;axisLine.lineStyle&apos;).getLineStyle()),
                    strokeContainThreshold: opt.strokeContainThreshold || 5,
                    silent: true,
                    z2: 1
                })));
            },
            axisTick: function () {
                var axisModel = this.axisModel;
                if (!axisModel.get(&apos;axisTick.show&apos;)) {
                    return;
                }
                var axis = axisModel.axis;
                var tickModel = axisModel.getModel(&apos;axisTick&apos;);
                var opt = this.opt;
                var lineStyleModel = tickModel.getModel(&apos;lineStyle&apos;);
                var tickLen = tickModel.get(&apos;length&apos;);
                var tickInterval = getInterval(tickModel, opt.labelInterval);
                var ticksCoords = axis.getTicksCoords(tickModel.get(&apos;alignWithLabel&apos;));
                var ticks = axis.scale.getTicks();
                var pt1 = [];
                var pt2 = [];
                var matrix = this._transform;
                for (var i = 0; i &lt; ticksCoords.length; i++) {
                    // Only ordinal scale support tick interval
                    if (ifIgnoreOnTick(axis, i, tickInterval)) {
                        continue;
                    }
                    var tickCoord = ticksCoords[i];
                    pt1[0] = tickCoord;
                    pt1[1] = 0;
                    pt2[0] = tickCoord;
                    pt2[1] = opt.tickDirection * tickLen;
                    if (matrix) {
                        v2ApplyTransform(pt1, pt1, matrix);
                        v2ApplyTransform(pt2, pt2, matrix);
                    }
                    // Tick line, Not use group transform to have better line draw
                    this.group.add(new graphic.Line(graphic.subPixelOptimizeLine({
                        anid: &apos;tick_&apos; + ticks[i],
                        shape: {
                            x1: pt1[0],
                            y1: pt1[1],
                            x2: pt2[0],
                            y2: pt2[1]
                        },
                        style: zrUtil.defaults(lineStyleModel.getLineStyle(), { stroke: axisModel.get(&apos;axisLine.lineStyle.color&apos;) }),
                        z2: 2,
                        silent: true
                    })));
                }
            },
            axisLabel: function () {
                var opt = this.opt;
                var axisModel = this.axisModel;
                var show = retrieve(opt.axisLabelShow, axisModel.get(&apos;axisLabel.show&apos;));
                if (!show) {
                    return;
                }
                var axis = axisModel.axis;
                var labelModel = axisModel.getModel(&apos;axisLabel&apos;);
                var textStyleModel = labelModel.getModel(&apos;textStyle&apos;);
                var labelMargin = labelModel.get(&apos;margin&apos;);
                var ticks = axis.scale.getTicks();
                var labels = axisModel.getFormattedLabels();
                // Special label rotate.
                var labelRotation = retrieve(opt.labelRotation, labelModel.get(&apos;rotate&apos;)) || 0;
                // To radian.
                labelRotation = labelRotation * PI / 180;
                var labelLayout = innerTextLayout(opt, labelRotation, opt.labelDirection);
                var categoryData = axisModel.get(&apos;data&apos;);
                var textEls = [];
                var silent = isSilent(axisModel);
                var triggerEvent = axisModel.get(&apos;triggerEvent&apos;);
                for (var i = 0; i &lt; ticks.length; i++) {
                    if (ifIgnoreOnTick(axis, i, opt.labelInterval)) {
                        continue;
                    }
                    var itemTextStyleModel = textStyleModel;
                    if (categoryData &amp;&amp; categoryData[i] &amp;&amp; categoryData[i].textStyle) {
                        itemTextStyleModel = new Model(categoryData[i].textStyle, textStyleModel, axisModel.ecModel);
                    }
                    var textColor = itemTextStyleModel.getTextColor() || axisModel.get(&apos;axisLine.lineStyle.color&apos;);
                    var tickCoord = axis.dataToCoord(ticks[i]);
                    var pos = [
                            tickCoord,
                            opt.labelOffset + opt.labelDirection * labelMargin
                        ];
                    var labelBeforeFormat = axis.scale.getLabel(ticks[i]);
                    var textEl = new graphic.Text({
                            anid: &apos;label_&apos; + ticks[i],
                            style: {
                                text: labels[i],
                                textAlign: itemTextStyleModel.get(&apos;align&apos;, true) || labelLayout.textAlign,
                                textVerticalAlign: itemTextStyleModel.get(&apos;baseline&apos;, true) || labelLayout.verticalAlign,
                                textFont: itemTextStyleModel.getFont(),
                                fill: typeof textColor === &apos;function&apos; ? textColor(labelBeforeFormat) : textColor
                            },
                            position: pos,
                            rotation: labelLayout.rotation,
                            silent: silent,
                            z2: 10
                        });
                    // Pack data for mouse event
                    if (triggerEvent) {
                        textEl.eventData = makeAxisEventDataBase(axisModel);
                        textEl.eventData.targetType = &apos;axisLabel&apos;;
                        textEl.eventData.value = labelBeforeFormat;
                    }
                    // FIXME
                    this._dumbGroup.add(textEl);
                    textEl.updateTransform();
                    textEls.push(textEl);
                    this.group.add(textEl);
                    textEl.decomposeTransform();
                }
                function isTwoLabelOverlapped(current, next) {
                    var firstRect = current &amp;&amp; current.getBoundingRect().clone();
                    var nextRect = next &amp;&amp; next.getBoundingRect().clone();
                    if (firstRect &amp;&amp; nextRect) {
                        firstRect.applyTransform(current.getLocalTransform());
                        nextRect.applyTransform(next.getLocalTransform());
                        return firstRect.intersect(nextRect);
                    }
                }
                if (axis.type !== &apos;category&apos;) {
                    // If min or max are user set, we need to check
                    // If the tick on min(max) are overlap on their neighbour tick
                    // If they are overlapped, we need to hide the min(max) tick label
                    if (axisModel.getMin ? axisModel.getMin() : axisModel.get(&apos;min&apos;)) {
                        var firstLabel = textEls[0];
                        var nextLabel = textEls[1];
                        if (isTwoLabelOverlapped(firstLabel, nextLabel)) {
                            firstLabel.ignore = true;
                        }
                    }
                    if (axisModel.getMax ? axisModel.getMax() : axisModel.get(&apos;max&apos;)) {
                        var lastLabel = textEls[textEls.length - 1];
                        var prevLabel = textEls[textEls.length - 2];
                        if (isTwoLabelOverlapped(prevLabel, lastLabel)) {
                            lastLabel.ignore = true;
                        }
                    }
                }
            },
            axisName: function () {
                var opt = this.opt;
                var axisModel = this.axisModel;
                var name = retrieve(opt.axisName, axisModel.get(&apos;name&apos;));
                if (!name) {
                    return;
                }
                var nameLocation = axisModel.get(&apos;nameLocation&apos;);
                var nameDirection = opt.nameDirection;
                var textStyleModel = axisModel.getModel(&apos;nameTextStyle&apos;);
                var gap = axisModel.get(&apos;nameGap&apos;) || 0;
                var extent = this.axisModel.axis.getExtent();
                var gapSignal = extent[0] &gt; extent[1] ? -1 : 1;
                var pos = [
                        nameLocation === &apos;start&apos; ? extent[0] - gapSignal * gap : nameLocation === &apos;end&apos; ? extent[1] + gapSignal * gap : (extent[0] + extent[1]) / 2,
                        nameLocation === &apos;middle&apos; ? opt.labelOffset + nameDirection * gap : 0
                    ];
                var labelLayout;
                var nameRotation = axisModel.get(&apos;nameRotate&apos;);
                if (nameRotation != null) {
                    nameRotation = nameRotation * PI / 180;    // To radian.
                }
                var axisNameAvailableWidth;
                if (nameLocation === &apos;middle&apos;) {
                    labelLayout = innerTextLayout(opt, nameRotation != null ? nameRotation : opt.rotation, nameDirection);
                } else {
                    labelLayout = endTextLayout(opt, nameLocation, nameRotation || 0, extent);
                    axisNameAvailableWidth = opt.axisNameAvailableWidth;
                    if (axisNameAvailableWidth != null) {
                        axisNameAvailableWidth = Math.abs(axisNameAvailableWidth / Math.sin(labelLayout.rotation));
                        !isFinite(axisNameAvailableWidth) &amp;&amp; (axisNameAvailableWidth = null);
                    }
                }
                var textFont = textStyleModel.getFont();
                var truncateOpt = axisModel.get(&apos;nameTruncate&apos;, true) || {};
                var ellipsis = truncateOpt.ellipsis;
                var maxWidth = retrieve(truncateOpt.maxWidth, axisNameAvailableWidth);
                var truncatedText = ellipsis != null &amp;&amp; maxWidth != null ? formatUtil.truncateText(name, maxWidth, textFont, ellipsis, {
                        minChar: 2,
                        placeholder: truncateOpt.placeholder
                    }) : name;
                var tooltipOpt = axisModel.get(&apos;tooltip&apos;, true);
                var mainType = axisModel.mainType;
                var formatterParams = {
                        componentType: mainType,
                        name: name,
                        $vars: [&apos;name&apos;]
                    };
                formatterParams[mainType + &apos;Index&apos;] = axisModel.componentIndex;
                var textEl = new graphic.Text({
                        anid: &apos;name&apos;,
                        __fullText: name,
                        __truncatedText: truncatedText,
                        style: {
                            text: truncatedText,
                            textFont: textFont,
                            fill: textStyleModel.getTextColor() || axisModel.get(&apos;axisLine.lineStyle.color&apos;),
                            textAlign: labelLayout.textAlign,
                            textVerticalAlign: labelLayout.verticalAlign
                        },
                        position: pos,
                        rotation: labelLayout.rotation,
                        silent: isSilent(axisModel),
                        z2: 1,
                        tooltip: tooltipOpt &amp;&amp; tooltipOpt.show ? zrUtil.extend({
                            content: name,
                            formatter: function () {
                                return name;
                            },
                            formatterParams: formatterParams
                        }, tooltipOpt) : null
                    });
                if (axisModel.get(&apos;triggerEvent&apos;)) {
                    textEl.eventData = makeAxisEventDataBase(axisModel);
                    textEl.eventData.targetType = &apos;axisName&apos;;
                    textEl.eventData.name = name;
                }
                // FIXME
                this._dumbGroup.add(textEl);
                textEl.updateTransform();
                this.group.add(textEl);
                textEl.decomposeTransform();
            }
        };
    /**
     * @inner
     */
    function innerTextLayout(opt, textRotation, direction) {
        var rotationDiff = remRadian(textRotation - opt.rotation);
        var textAlign;
        var verticalAlign;
        if (isRadianAroundZero(rotationDiff)) {
            // Label is parallel with axis line.
            verticalAlign = direction &gt; 0 ? &apos;top&apos; : &apos;bottom&apos;;
            textAlign = &apos;center&apos;;
        } else if (isRadianAroundZero(rotationDiff - PI)) {
            // Label is inverse parallel with axis line.
            verticalAlign = direction &gt; 0 ? &apos;bottom&apos; : &apos;top&apos;;
            textAlign = &apos;center&apos;;
        } else {
            verticalAlign = &apos;middle&apos;;
            if (rotationDiff &gt; 0 &amp;&amp; rotationDiff &lt; PI) {
                textAlign = direction &gt; 0 ? &apos;right&apos; : &apos;left&apos;;
            } else {
                textAlign = direction &gt; 0 ? &apos;left&apos; : &apos;right&apos;;
            }
        }
        return {
            rotation: rotationDiff,
            textAlign: textAlign,
            verticalAlign: verticalAlign
        };
    }
    /**
     * @inner
     */
    function endTextLayout(opt, textPosition, textRotate, extent) {
        var rotationDiff = remRadian(textRotate - opt.rotation);
        var textAlign;
        var verticalAlign;
        var inverse = extent[0] &gt; extent[1];
        var onLeft = textPosition === &apos;start&apos; &amp;&amp; !inverse || textPosition !== &apos;start&apos; &amp;&amp; inverse;
        if (isRadianAroundZero(rotationDiff - PI / 2)) {
            verticalAlign = onLeft ? &apos;bottom&apos; : &apos;top&apos;;
            textAlign = &apos;center&apos;;
        } else if (isRadianAroundZero(rotationDiff - PI * 1.5)) {
            verticalAlign = onLeft ? &apos;top&apos; : &apos;bottom&apos;;
            textAlign = &apos;center&apos;;
        } else {
            verticalAlign = &apos;middle&apos;;
            if (rotationDiff &lt; PI * 1.5 &amp;&amp; rotationDiff &gt; PI / 2) {
                textAlign = onLeft ? &apos;left&apos; : &apos;right&apos;;
            } else {
                textAlign = onLeft ? &apos;right&apos; : &apos;left&apos;;
            }
        }
        return {
            rotation: rotationDiff,
            textAlign: textAlign,
            verticalAlign: verticalAlign
        };
    }
    /**
     * @inner
     */
    function isSilent(axisModel) {
        var tooltipOpt = axisModel.get(&apos;tooltip&apos;);
        return axisModel.get(&apos;silent&apos;) || !(axisModel.get(&apos;triggerEvent&apos;) || tooltipOpt &amp;&amp; tooltipOpt.show);
    }
    /**
     * @static
     */
    var ifIgnoreOnTick = AxisBuilder.ifIgnoreOnTick = function (axis, i, interval) {
            var rawTick;
            var scale = axis.scale;
            return scale.type === &apos;ordinal&apos; &amp;&amp; (typeof interval === &apos;function&apos; ? (rawTick = scale.getTicks()[i], !interval(rawTick, scale.getLabel(rawTick))) : i % (interval + 1));
        };
    /**
     * @static
     */
    var getInterval = AxisBuilder.getInterval = function (model, labelInterval) {
            var interval = model.get(&apos;interval&apos;);
            if (interval == null || interval == &apos;auto&apos;) {
                interval = labelInterval;
            }
            return interval;
        };
    return AxisBuilder;
});
define(&apos;zrender&apos;, [&apos;zrender/zrender&apos;], function (zrender) { return zrender;});
define(&apos;echarts&apos;, [&apos;echarts/echarts&apos;], function (echarts) { return echarts;});
var echarts = require(&apos;echarts&apos;);

echarts.graphic = require(&apos;echarts/util/graphic&apos;);
echarts.number = require(&apos;echarts/util/number&apos;);
echarts.format = require(&apos;echarts/util/format&apos;);


require(&apos;echarts/chart/pie&apos;);

require(&apos;echarts/chart/radar&apos;);


require(&apos;echarts/component/polar&apos;);

require(&apos;echarts/component/title&apos;);

require(&apos;echarts/component/legend&apos;);

require(&apos;echarts/component/tooltip&apos;);




return echarts;
}));</number></=></=></string></string></string></string></object></https:></string,></string,></number></=></=></=></=></=></number></number></number></number></number></number></number></number></=></number></=></=></=></=></=></number></=></=></=></=></=></=></=></=></=></=></number></=></=></=></=></=></=></=></object></object></object></=></object></=></module:zrender></number></number></number></number></number></number></number></string></=></string></=></=></=></=></=></string></string></subkey,></object></array.<object></object></object></object></object></module:echarts></object></number|string|date></string></string></string></string></number></=></number></number></string></string></number></string,></number></array.<object></number></=></object></number></string></=></=></=></=></=></=></=></=></number></number></=></=></number></number></number></number></string></string></string></string></=></=></=></string></object|number|array></array|object></module:zrender></object></object></module:echarts></string></string></key,></number></string></=></=></=></number></number></array.<number></number></=></number></number></=></=></number></number></number></number></number></=></=></http:></number></object></number></object></string></nubmer></string,></=></=></module:echarts~echarts></key,></object.<string,></function></object.<string,></function></string,></module:echarts></string,></module:echarts>